All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ben Greear <greearb-my8/4N5VtI7c+919tysfdA@public.gmane.org>
To: Jeff Layton <jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
Cc: sfrench-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org,
	linux-cifs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: Re: [cifs bindaddr v3] cifs:  Allow binding to local IP address.
Date: Wed, 01 Sep 2010 09:31:24 -0700	[thread overview]
Message-ID: <4C7E7FDC.7060606@candelatech.com> (raw)
In-Reply-To: <20100901084147.4aa66e9d-4QP7MXygkU+dMjc06nkz3ljfA9RmPOcC@public.gmane.org>

On 09/01/2010 05:41 AM, Jeff Layton wrote:
> On Tue, 31 Aug 2010 12:55:14 -0700
> Ben Greear<greearb-my8/4N5VtI7c+919tysfdA@public.gmane.org>  wrote:
>
>> When using multi-homed machines, it's nice to be able to specify
>> the local IP to use for outbound connections.  This patch gives
>> cifs the ability to bind to a particular IP address.
>>
>>     Usage:  mount -t cifs -o srcaddr=192.168.1.50,user=foo, ...
>>     Usage:  mount -t cifs -o srcaddr=2002::100:1,user=foo, ...
>>
>> Signed-off-by: Ben Greear<greearb-my8/4N5VtI7c+919tysfdA@public.gmane.org>

>> +bool
>> +cifs_addr_is_specified(struct sockaddr *srcaddr) {
>> +	struct sockaddr_in *saddr4 = (struct sockaddr_in *)srcaddr;
>> +	struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *)srcaddr;
>> +	static const struct in6_addr c_in6addr_any = IN6ADDR_ANY_INIT;
>> +	switch (srcaddr->sa_family) {
>> +	case AF_INET:
>> +		return saddr4->sin_addr.s_addr != 0;
>> +	case AF_INET6:
>> +		return (!ipv6_addr_equal(&c_in6addr_any,&saddr6->sin6_addr));
>> +	}
>> +	return false;
>> +}
>> +
>
> I don't think you need all of this. cifs_addr_is_specified ought to
> just be srcaddr->sa_family != AF_UNSPEC. That could be a static inline
> or macro, even.

Yeah, I'll fix that next patch.

>> +/** Returns true if srcaddr isn't specified and rhs isn't
>> + * specified, or if srcaddr is specified and
>> + * matches the IP address of the rhs argument.
>> + */
>> +static bool
>> +srcip_matches(struct sockaddr *srcaddr, struct sockaddr *rhs)
>> +{
>> +	if (cifs_addr_is_specified(srcaddr)) {
>> +		struct sockaddr_in *saddr4 = (struct sockaddr_in *)srcaddr;
>> +		struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *)srcaddr;
>> +		struct sockaddr_in *vaddr4 = (struct sockaddr_in *)rhs;
>> +		struct sockaddr_in6 *vaddr6 = (struct sockaddr_in6 *)&rhs;
>> +
>> +		switch (srcaddr->sa_family) {
>> +		case AF_INET:
>> +			if (saddr4->sin_addr.s_addr != vaddr4->sin_addr.s_addr)
>> +				return false;
>> +			break;
>> +		case AF_INET6:
>> +			if (!ipv6_addr_equal(&saddr6->sin6_addr,
>> +					&vaddr6->sin6_addr))
>> +				return false;
>> +			break;
>> +		default:
>> +			return false;
>> +		}
>> +		return true;
>> +	}
>> +	else
>> +		return !cifs_addr_is_specified(rhs);
>> +}
>
> This is more complicated than it really needs to be I think. I think
> all what you really need to do here is check to see if the address
> families match. If they do and they're either AF_INET flavor, then check
> to see if the addresses match. You might even be able to reuse some of
> the code in match_address here.

I think I'm basically doing what you suggest, with the only trick that
any un-bound (non-specified) addresses must match only other non-specified
connections.

Please post an improved version of this method if you have one to
suggest, but I don't see any way to significantly simplify this.

>> +static int
>> +bind_socket(struct TCP_Server_Info *server)
>> +{
>> +	int rc = 0;
>> +	if (cifs_addr_is_specified((struct sockaddr *)&server->srcaddr)) {
>> +		/* Bind to the local IP address if specified */
>> +		struct socket *socket = server->ssocket;
>> +		rc = socket->ops->bind(socket,
>> +				       (struct sockaddr *)&server->srcaddr,
>> +				       sizeof(server->srcaddr));
>> +		if (rc<  0) {
>> +			struct sockaddr_in *saddr4;
>> +			struct sockaddr_in6 *saddr6;
>> +			saddr4 = (struct sockaddr_in *)&server->srcaddr;
>> +			saddr6 = (struct sockaddr_in6 *)&server->srcaddr;
>> +			if (saddr6->sin6_family == AF_INET6)
>> +				printk(KERN_WARNING "cifs: "
>> +				       "Failed to bind to: %pI6c, error: %d\n",
>> +				&saddr6->sin6_addr, rc);
>> +			else
>> +				printk(KERN_WARNING "cifs: "
>> +				       "Failed to bind to: %pI4, error: %d\n",
>> +				&saddr4->sin_addr.s_addr, rc);
>> +		}
> 			^^^^^^^^^^^
> For better or worse, the CIFS code uses the cFYI and cERROR macros for
> printk's. You should probably do the same here.

If I make these cERROR, will they be printed to /var/log/messages
and/or dmesg by default if the error case hits?  I definately want this
visible in the logs by default so users have a chance of figuring out why
the bind failed.

> ^^^^
> The printk's are nice and all, but shouldn't you fail the
> ipv[4,6]_connect if the socket can't be bound?

Either way is fine with me.  It would be possible for the actual
connection to still work in the bind-failure case, but it might not
be what the user would expect.

Thanks,
Ben

-- 
Ben Greear <greearb-my8/4N5VtI7c+919tysfdA@public.gmane.org>
Candela Technologies Inc  http://www.candelatech.com

  parent reply	other threads:[~2010-09-01 16:31 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-08-31 19:55 [cifs bindaddr v3] cifs: Allow binding to local IP address Ben Greear
     [not found] ` <1283284514-25588-1-git-send-email-greearb-my8/4N5VtI7c+919tysfdA@public.gmane.org>
2010-09-01 12:41   ` Jeff Layton
     [not found]     ` <AANLkTi=hKNekX4_8RMm+OLvoPQahYHY-8iNm=ELFFPqS@mail.gmail.com>
     [not found]       ` <AANLkTi=hKNekX4_8RMm+OLvoPQahYHY-8iNm=ELFFPqS-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2010-09-01 13:50         ` Fwd: " Steve French
     [not found]     ` <20100901084147.4aa66e9d-4QP7MXygkU+dMjc06nkz3ljfA9RmPOcC@public.gmane.org>
2010-09-01 16:31       ` Ben Greear [this message]
     [not found]         ` <4C7E7FDC.7060606-my8/4N5VtI7c+919tysfdA@public.gmane.org>
2010-09-01 16:40           ` Jeff Layton
2010-09-01 16:46           ` Steve French
  -- strict thread matches above, loose matches on Subject: below --
2010-08-26 17:34 [cifs bindaddr v2] " Ben Greear
     [not found] ` <AANLkTik4Cffnr0ciYAVXz_jb_=EG5kBaKNE3V3cNVtwf@mail.gmail.com>
     [not found]   ` <4C777615.2080109@erion.co.uk>
     [not found]     ` <AANLkTi=9xBr2gABJSUSk2DMJEYho+jA3rbCk1PSfuQQ5@mail.gmail.com>
     [not found]       ` <20100827095433.26bb3c3e@corrin.poochiereds.net>
2010-08-27 15:29         ` Ben Greear
2010-08-27 16:52           ` Jeff Layton
2010-08-27 17:08             ` Steve French
2010-08-27 17:12               ` Ben Greear
2010-08-27 17:34                 ` Jeff Layton
2010-08-27 17:59                   ` Steve French
     [not found]                     ` <AANLkTikDjbWv0F18WevNbsfJyutEu28RCCgtmp1=ZBd4-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2010-08-30 18:19                       ` [cifs bindaddr v3] " Ben Greear

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4C7E7FDC.7060606@candelatech.com \
    --to=greearb-my8/4n5vti7c+919tysfda@public.gmane.org \
    --cc=jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org \
    --cc=linux-cifs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=sfrench-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.