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
next prev 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox