net/ipv6/addrconf: fix wdog_bark caused by infinite spinning on a deadlock

A synchronization issue may occur while addrconf_ifdown(),
when it updates inet6_addr_lst[] with already destroyed *ifp
by ipv6_add/del_addr(), using the same addrconf_hash_lock.

[core 0]                                        [core 1]
   |                                               |
   |->ipv6_add_addr                                |->addrconf_ifdown
       |                                               |
       |                                               |-> spin_lock(&addrconf_hash_lock);
       |                                               |-> remove ifa->addr_lst from inet6_addr_lst
       |                                               |-> spin_unlock(&addrconf_hash_lock);
       |-> spin_lock(&addrconf_hash_lock);             |
       |-> add ifa->addr_lst to inet6_addr_lst[hash]   |
       |-> spin_unlock(&addrconf_hash_lock);           |
       |-> write_lock(&idev-lock);                     |
       |-> add ifa->if_list to idev->addr_list         |
       |-> write_unlock(&idev->lock);                  |
       |                                               |-> write_lock(&idev->lock);
       |                                               |-> remove ifa->if_list from idev->addr_list
       |                                               |-> write_unlock(&idev->lock);

[28055.378524] ------------[ cut here ]------------
[28055.378591] WARNING: at net/ipv6/addrconf.c:546 inet6_ifa_finish_destroy+0x98/0xc8()
[28055.378691] [<c010de1c>] (unwind_backtrace+0x0/0x144) from [<c09fd08c>] (dump_stack+0x20/0x24)
[28055.378747] [<c09fd08c>] (dump_stack+0x20/0x24) from [<c0192adc>] (warn_slowpath_common+0x58/0x70)
[28055.378840] [<c0192adc>] (warn_slowpath_common+0x58/0x70) from [<c0192bec>] (warn_slowpath_null+0x2c/0x34)
[28055.378931] [<c0192bec>] (warn_slowpath_null+0x2c/0x34) from [<c0911a90>] (inet6_ifa_finish_destroy+0x98/0xc8)
[28055.379026] [<c0911a90>] (inet6_ifa_finish_destroy+0x98/0xc8) from [<c091498c>] (addrconf_ifdown+0x2e4/0x430)
[28055.379120] [<c091498c>] (addrconf_ifdown+0x2e4/0x430) from [<c0915b70>] (addrconf_notify+0xe4/0x3ac)
[28055.379209] [<c0915b70>] (addrconf_notify+0xe4/0x3ac) from [<c01b9df0>] (notifier_call_chain+0x54/0x94)
[28055.379321] [<c01b9df0>] (notifier_call_chain+0x54/0x94) from [<c01ba3ac>] (__raw_notifier_call_chain+0x24/0x2c)
[28055.379379] [<c01ba3ac>] (__raw_notifier_call_chain+0x24/0x2c) from [<c01ba3dc>] (raw_notifier_call_chain+0x28/0x30)
[28055.379475] [<c01ba3dc>] (raw_notifier_call_chain+0x28/0x30) from [<c0840ea4>] (call_netdevice_notifiers+0x38/0x60)
[28055.379568] [<c0840ea4>] (call_netdevice_notifiers+0x38/0x60) from [<c0844d5c>] (__dev_notify_flags+0x3c/0x6c)
[28055.379657] [<c0844d5c>] (__dev_notify_flags+0x3c/0x6c) from [<c0844dcc>] (dev_change_flags+0x40/0x58)
[28055.379747] [<c0844dcc>] (dev_change_flags+0x40/0x58) from [<c08d2834>] (devinet_ioctl+0x79c/0x8bc)
[28055.379837] [<c08d2834>] (devinet_ioctl+0x79c/0x8bc) from [<c08d3488>] (inet_ioctl+0x1c0/0x1d0)
[28055.379928] [<c08d3488>] (inet_ioctl+0x1c0/0x1d0) from [<c082d7f0>] (sock_ioctl+0x80/0x248)
[28055.379982] [<c082d7f0>] (sock_ioctl+0x80/0x248) from [<c0275364>] (do_vfs_ioctl+0x94/0x5bc)
[28055.380071] [<c0275364>] (do_vfs_ioctl+0x94/0x5bc) from [<c0275908>] (sys_ioctl+0x7c/0x8c)
[28055.380164] [<c0275908>] (sys_ioctl+0x7c/0x8c) from [<c0107300>] (ret_fast_syscall+0x0/0x30)
[28055.380252] ---[ end trace 920b8b321354f066 ]---
[28061.735021] Watchdog bark! Now = 28061.735014
[28061.735106] Watchdog last pet at 28050.179294
[28061.735245] cpu alive mask from last pet 0-3
[28061.735321] Causing a watchdog bite!

The addrconf_hash_lock should cover both modification of inet6_addr_list and idev->addr_list
to resolve any possible synchronization issue between addrconf_ifdown() and ipv6_add/del_addr().

Bug: 11293746
Signed-off-by: David C. Park <davidc.park@lge.com>

Signed-off-by: Chet Kener <Cl3Kener@gmail.com>
net: ipv6: ping: Use socket mark in routing lookup

[net-next commit bf439b3154ce49d81a79b14f9fab18af99018ae2]

Change-Id: I8356e9132088c75d4510021c6e4c2641d772087a
Signed-off-by: Lorenzo Colitti <lorenzo@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Chet Kener <Cl3Kener@gmail.com>
net: ipv6: autoconf routes into per-device tables

Currently, IPv6 router discovery always puts routes into
RT6_TABLE_MAIN. This causes problems for connection managers
that want to support multiple simultaneous network connections
and want control over which one is used by default (e.g., wifi
and wired).

To work around this connection managers typically take the routes
they prefer and copy them to static routes with low metrics in
the main table. This puts the burden on the connection manager
to watch netlink to see if the routes have changed, delete the
routes when their lifetime expires, etc.

Instead, this patch adds a per-interface sysctl to have the
kernel put autoconf routes into different tables. This allows
each interface to have its own autoconf table, and choosing the
default interface (or using different interfaces at the same
time for different types of traffic) can be done using
appropriate ip rules.

The sysctl behaves as follows:

- = 0: default. Put routes into RT6_TABLE_MAIN as before.
- > 0: manual. Put routes into the specified table.
- < 0: automatic. Add the absolute value of the sysctl to the
       device's ifindex, and use that table.

The automatic mode is most useful in conjunction with
net.ipv6.conf.default.accept_ra_rt_table. A connection manager
or distribution could set it to, say, -100 on boot, and
thereafter just use IP rules.

Change-Id: I093d39fb06ec413905dc0d0d5792c1bc5d5c73a9
Signed-off-by: Lorenzo Colitti <lorenzo@google.com>
Signed-off-by: Chet Kener <Cl3Kener@gmail.com>

Conflicts:
	net/ipv6/route.c
net: support marking accepting TCP sockets

When using mark-based routing, sockets returned from accept()
may need to be marked differently depending on the incoming
connection request.

This is the case, for example, if different socket marks identify
different networks: a listening socket may want to accept
connections from all networks, but each connection should be
marked with the network that the request came in on, so that
subsequent packets are sent on the correct network.

This patch adds a sysctl to mark TCP sockets based on the fwmark
of the incoming SYN packet. If enabled, and an unmarked socket
receives a SYN, then the SYN packet's fwmark is written to the
connection's inet_request_sock, and later written back to the
accepted socket when the connection is established.  If the
socket already has a nonzero mark, then the behaviour is the same
as it is today, i.e., the listening socket's fwmark is used.

Black-box tested using user-mode linux:

- IPv4/IPv6 SYN+ACK, FIN, etc. packets are routed based on the
  mark of the incoming SYN packet.
- The socket returned by accept() is marked with the mark of the
  incoming SYN packet.
- Tested with syncookies=1 and syncookies=2.

Change-Id: I5e8c9b989762a93f3eb5a0c1b4df44f62d57f3cb
Signed-off-by: Lorenzo Colitti <lorenzo@google.com>
Signed-off-by: Chet Kener <Cl3Kener@gmail.com>
net: core: Support UID-based routing.

This contains the following commits:

1. 0149763 net: core: Add a UID range to fib rules.
2. 1650474 net: core: Use the socket UID in routing lookups.
3. 0b16771 net: ipv4: Add the UID to the route cache.
4. ee058f1 net: core: Add a RTA_UID attribute to routes.
    This is so that userspace can do per-UID route lookups.

Bug: 15413527
Change-Id: I1285474c6734614d3bda6f61d88dfe89a4af7892
Signed-off-by: Lorenzo Colitti <lorenzo@google.com>
Signed-off-by: Chet Kener <Cl3Kener@gmail.com>

Conflicts:
	include/net/route.h