Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 290056
b: refs/heads/master
c: 76e2105
h: refs/heads/master
v: v3
  • Loading branch information
Erich E. Hoover authored and David S. Miller committed Feb 8, 2012
1 parent b5bffee commit 1cd88d8
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 4 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 43480aecb1f538d4f6dd8b2c5d2b71fb98659072
refs/heads/master: 76e21053b5bf33a07c76f99d27a74238310e3c71
1 change: 1 addition & 0 deletions trunk/include/linux/in.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ struct in_addr {
#define MCAST_LEAVE_SOURCE_GROUP 47
#define MCAST_MSFILTER 48
#define IP_MULTICAST_ALL 49
#define IP_UNICAST_IF 50

#define MCAST_EXCLUDE 0
#define MCAST_INCLUDE 1
Expand Down
2 changes: 2 additions & 0 deletions trunk/include/net/inet_sock.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ struct rtable;
* @tos - TOS
* @mc_ttl - Multicasting TTL
* @is_icsk - is this an inet_connection_sock?
* @uc_index - Unicast outgoing device index
* @mc_index - Multicast device index
* @mc_list - Group array
* @cork - info to build ip hdr on each ip frag while socket is corked
Expand Down Expand Up @@ -167,6 +168,7 @@ struct inet_sock {
transparent:1,
mc_all:1,
nodefrag:1;
int uc_index;
int mc_index;
__be32 mc_addr;
struct ip_mc_socklist __rcu *mc_list;
Expand Down
33 changes: 33 additions & 0 deletions trunk/net/ipv4/ip_sockglue.c
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,7 @@ static int do_ip_setsockopt(struct sock *sk, int level,
(1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) |
(1<<IP_PASSSEC) | (1<<IP_TRANSPARENT) |
(1<<IP_MINTTL) | (1<<IP_NODEFRAG))) ||
optname == IP_UNICAST_IF ||
optname == IP_MULTICAST_TTL ||
optname == IP_MULTICAST_ALL ||
optname == IP_MULTICAST_LOOP ||
Expand Down Expand Up @@ -628,6 +629,35 @@ static int do_ip_setsockopt(struct sock *sk, int level,
goto e_inval;
inet->mc_loop = !!val;
break;
case IP_UNICAST_IF:
{
struct net_device *dev = NULL;
int ifindex;

if (optlen != sizeof(int))
goto e_inval;

ifindex = (__force int)ntohl((__force __be32)val);
if (ifindex == 0) {
inet->uc_index = 0;
err = 0;
break;
}

dev = dev_get_by_index(sock_net(sk), ifindex);
err = -EADDRNOTAVAIL;
if (!dev)
break;
dev_put(dev);

err = -EINVAL;
if (sk->sk_bound_dev_if)
break;

inet->uc_index = ifindex;
err = 0;
break;
}
case IP_MULTICAST_IF:
{
struct ip_mreqn mreq;
Expand Down Expand Up @@ -1178,6 +1208,9 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
case IP_MULTICAST_LOOP:
val = inet->mc_loop;
break;
case IP_UNICAST_IF:
val = (__force int)htonl((__u32) inet->uc_index);
break;
case IP_MULTICAST_IF:
{
struct in_addr addr;
Expand Down
3 changes: 2 additions & 1 deletion trunk/net/ipv4/ping.c
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,8 @@ static int ping_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
ipc.oif = inet->mc_index;
if (!saddr)
saddr = inet->mc_addr;
}
} else if (!ipc.oif)
ipc.oif = inet->uc_index;

flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos,
RT_SCOPE_UNIVERSE, sk->sk_protocol,
Expand Down
3 changes: 2 additions & 1 deletion trunk/net/ipv4/raw.c
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,8 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
ipc.oif = inet->mc_index;
if (!saddr)
saddr = inet->mc_addr;
}
} else if (!ipc.oif)
ipc.oif = inet->uc_index;

flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos,
RT_SCOPE_UNIVERSE,
Expand Down
3 changes: 2 additions & 1 deletion trunk/net/ipv4/udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -917,7 +917,8 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
if (!saddr)
saddr = inet->mc_addr;
connected = 0;
}
} else if (!ipc.oif)
ipc.oif = inet->uc_index;

if (connected)
rt = (struct rtable *)sk_dst_check(sk, 0);
Expand Down

0 comments on commit 1cd88d8

Please sign in to comment.