Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetoot...
authorDavid S. Miller <davem@davemloft.net>
Fri, 18 Sep 2015 05:25:51 +0000 (22:25 -0700)
committerDavid S. Miller <davem@davemloft.net>
Fri, 18 Sep 2015 05:25:51 +0000 (22:25 -0700)
Johan Hedberg says:

====================
pull request: bluetooth 2015-09-17

Here's one important patch for the 4.3-rc series that fixes an issue
with Bluetooth LE encryption failing because of a too early check for
the SMP context.

Please let me know if there are any issues pulling. Thanks.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
19 files changed:
Documentation/networking/vrf.txt [new file with mode: 0644]
Documentation/sysctl/net.txt
MAINTAINERS
drivers/atm/solos-pci.c
drivers/net/ethernet/chelsio/cxgb4/t4_pci_id_tbl.h
drivers/net/ethernet/mellanox/mlx4/en_rx.c
drivers/net/ethernet/micrel/ks8851.c
drivers/net/vrf.c
include/net/flow.h
include/net/ip6_fib.h
include/net/route.h
net/atm/clip.c
net/ipv4/fib_trie.c
net/ipv4/udp.c
net/ipv4/xfrm4_policy.c
net/ipv6/ip6_fib.c
net/ipv6/ip6_output.c
net/ipv6/route.c
net/openvswitch/conntrack.c

diff --git a/Documentation/networking/vrf.txt b/Documentation/networking/vrf.txt
new file mode 100644 (file)
index 0000000..031ef4a
--- /dev/null
@@ -0,0 +1,96 @@
+Virtual Routing and Forwarding (VRF)
+====================================
+The VRF device combined with ip rules provides the ability to create virtual
+routing and forwarding domains (aka VRFs, VRF-lite to be specific) in the
+Linux network stack. One use case is the multi-tenancy problem where each
+tenant has their own unique routing tables and in the very least need
+different default gateways.
+
+Processes can be "VRF aware" by binding a socket to the VRF device. Packets
+through the socket then use the routing table associated with the VRF
+device. An important feature of the VRF device implementation is that it
+impacts only Layer 3 and above so L2 tools (e.g., LLDP) are not affected
+(ie., they do not need to be run in each VRF). The design also allows
+the use of higher priority ip rules (Policy Based Routing, PBR) to take
+precedence over the VRF device rules directing specific traffic as desired.
+
+In addition, VRF devices allow VRFs to be nested within namespaces. For
+example network namespaces provide separation of network interfaces at L1
+(Layer 1 separation), VLANs on the interfaces within a namespace provide
+L2 separation and then VRF devices provide L3 separation.
+
+Design
+------
+A VRF device is created with an associated route table. Network interfaces
+are then enslaved to a VRF device:
+
+         +-----------------------------+
+         |           vrf-blue          |  ===> route table 10
+         +-----------------------------+
+            |        |            |
+         +------+ +------+     +-------------+
+         | eth1 | | eth2 | ... |    bond1    |
+         +------+ +------+     +-------------+
+                                  |       |
+                              +------+ +------+
+                              | eth8 | | eth9 |
+                              +------+ +------+
+
+Packets received on an enslaved device and are switched to the VRF device
+using an rx_handler which gives the impression that packets flow through
+the VRF device. Similarly on egress routing rules are used to send packets
+to the VRF device driver before getting sent out the actual interface. This
+allows tcpdump on a VRF device to capture all packets into and out of the
+VRF as a whole.[1] Similiarly, netfilter [2] and tc rules can be applied
+using the VRF device to specify rules that apply to the VRF domain as a whole.
+
+[1] Packets in the forwarded state do not flow through the device, so those
+    packets are not seen by tcpdump. Will revisit this limitation in a
+    future release.
+
+[2] Iptables on ingress is limited to NF_INET_PRE_ROUTING only with skb->dev
+    set to real ingress device and egress is limited to NF_INET_POST_ROUTING.
+    Will revisit this limitation in a future release.
+
+
+Setup
+-----
+1. VRF device is created with an association to a FIB table.
+   e.g, ip link add vrf-blue type vrf table 10
+        ip link set dev vrf-blue up
+
+2. Rules are added that send lookups to the associated FIB table when the
+   iif or oif is the VRF device. e.g.,
+       ip ru add oif vrf-blue table 10
+       ip ru add iif vrf-blue table 10
+
+   Set the default route for the table (and hence default route for the VRF).
+   e.g, ip route add table 10 prohibit default
+
+3. Enslave L3 interfaces to a VRF device.
+   e.g,  ip link set dev eth1 master vrf-blue
+
+   Local and connected routes for enslaved devices are automatically moved to
+   the table associated with VRF device. Any additional routes depending on
+   the enslaved device will need to be reinserted following the enslavement.
+
+4. Additional VRF routes are added to associated table.
+   e.g., ip route add table 10 ...
+
+
+Applications
+------------
+Applications that are to work within a VRF need to bind their socket to the
+VRF device:
+
+    setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, dev, strlen(dev)+1);
+
+or to specify the output device using cmsg and IP_PKTINFO.
+
+
+Limitations
+-----------
+VRF device currently only works for IPv4. Support for IPv6 is under development.
+
+Index of original ingress interface is not available via cmsg. Will address
+soon.
index 6294b5186ae552b8b2fcb78ac4b8617ee6f8fe38..809ab6efcc744ec3dcad28bb075d696e6613f836 100644 (file)
@@ -54,13 +54,15 @@ default_qdisc
 --------------
 
 The default queuing discipline to use for network devices. This allows
-overriding the default queue discipline of pfifo_fast with an
-alternative. Since the default queuing discipline is created with the
-no additional parameters so is best suited to queuing disciplines that
-work well without configuration like stochastic fair queue (sfq),
-CoDel (codel) or fair queue CoDel (fq_codel). Don't use queuing disciplines
-like Hierarchical Token Bucket or Deficit Round Robin which require setting
-up classes and bandwidths.
+overriding the default of pfifo_fast with an alternative. Since the default
+queuing discipline is created without additional parameters so is best suited
+to queuing disciplines that work well without configuration like stochastic
+fair queue (sfq), CoDel (codel) or fair queue CoDel (fq_codel). Don't use
+queuing disciplines like Hierarchical Token Bucket or Deficit Round Robin
+which require setting up classes and bandwidths. Note that physical multiqueue
+interfaces still use mq as root qdisc, which in turn uses this default for its
+leaves. Virtual devices (like e.g. lo or veth) ignore this setting and instead
+default to noqueue.
 Default: pfifo_fast
 
 busy_read
index 310da4295c7026e27698e9f8b980adcc1893b774..d4d9d4f6d271867b72046a4b3e866ed7057b9894 100644 (file)
@@ -11243,6 +11243,7 @@ L:      netdev@vger.kernel.org
 S:     Maintained
 F:     drivers/net/vrf.c
 F:     include/net/vrf.h
+F:     Documentation/networking/vrf.txt
 
 VT1211 HARDWARE MONITOR DRIVER
 M:     Juerg Haefliger <juergh@gmail.com>
index 74e18b0a6d8945ac6df8537d394729354769e6da..3d7fb6516f74f83cd9276b4d5ff4d0a19d403241 100644 (file)
@@ -805,7 +805,12 @@ static void solos_bh(unsigned long card_arg)
                                        continue;
                                }
 
-                               skb = alloc_skb(size + 1, GFP_ATOMIC);
+                               /* Use netdev_alloc_skb() because it adds NET_SKB_PAD of
+                                * headroom, and ensures we can route packets back out an
+                                * Ethernet interface (for example) without having to
+                                * reallocate. Adding NET_IP_ALIGN also ensures that both
+                                * PPPoATM and PPPoEoBR2684 packets end up aligned. */
+                               skb = netdev_alloc_skb_ip_align(NULL, size + 1);
                                if (!skb) {
                                        if (net_ratelimit())
                                                dev_warn(&card->dev->dev, "Failed to allocate sk_buff for RX\n");
@@ -869,7 +874,10 @@ static void solos_bh(unsigned long card_arg)
                /* Allocate RX skbs for any ports which need them */
                if (card->using_dma && card->atmdev[port] &&
                    !card->rx_skb[port]) {
-                       struct sk_buff *skb = alloc_skb(RX_DMA_SIZE, GFP_ATOMIC);
+                       /* Unlike the MMIO case (qv) we can't add NET_IP_ALIGN
+                        * here; the FPGA can only DMA to addresses which are
+                        * aligned to 4 bytes. */
+                       struct sk_buff *skb = dev_alloc_skb(RX_DMA_SIZE);
                        if (skb) {
                                SKB_CB(skb)->dma_addr =
                                        dma_map_single(&card->dev->dev, skb->data,
index 8353a6cbfcc21edd2dde363fafd06b202611cae4..03ed00c498230d4a0daeeccb3016a863d6445a29 100644 (file)
@@ -157,6 +157,11 @@ CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN
        CH_PCI_ID_TABLE_FENTRY(0x5090), /* Custom T540-CR */
        CH_PCI_ID_TABLE_FENTRY(0x5091), /* Custom T522-CR */
        CH_PCI_ID_TABLE_FENTRY(0x5092), /* Custom T520-CR */
+       CH_PCI_ID_TABLE_FENTRY(0x5093), /* Custom T580-LP-CR */
+       CH_PCI_ID_TABLE_FENTRY(0x5094), /* Custom T540-CR */
+       CH_PCI_ID_TABLE_FENTRY(0x5095), /* Custom T540-CR-SO */
+       CH_PCI_ID_TABLE_FENTRY(0x5096), /* Custom T580-CR */
+       CH_PCI_ID_TABLE_FENTRY(0x5097), /* Custom T520-KR */
 
        /* T6 adapters:
         */
index 4402a1e48c9bb9d8153df9e9f9378d5e4ece38b3..0ce6ffe73ca80a49dd209f8c98bc3fea92899138 100644 (file)
@@ -1268,8 +1268,6 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv)
                rss_context->hash_fn = MLX4_RSS_HASH_TOP;
                memcpy(rss_context->rss_key, priv->rss_key,
                       MLX4_EN_RSS_KEY_SIZE);
-               netdev_rss_key_fill(rss_context->rss_key,
-                                   MLX4_EN_RSS_KEY_SIZE);
        } else {
                en_err(priv, "Unknown RSS hash function requested\n");
                err = -EINVAL;
index 66d4ab703f45a20b7949e1bd3e448c9dc182e68f..60f43ec2217532abae6c7d4e9529c7db4eb23b4b 100644 (file)
@@ -1601,6 +1601,7 @@ static const struct of_device_id ks8851_match_table[] = {
        { .compatible = "micrel,ks8851" },
        { }
 };
+MODULE_DEVICE_TABLE(of, ks8851_match_table);
 
 static struct spi_driver ks8851_driver = {
        .driver = {
index e7094fbd75685998bb5ee492367e686c133a2e15..488c6f50df736968cee60af48d0360924a9f2e2b 100644 (file)
@@ -193,7 +193,8 @@ static netdev_tx_t vrf_process_v4_outbound(struct sk_buff *skb,
                .flowi4_oif = vrf_dev->ifindex,
                .flowi4_iif = LOOPBACK_IFINDEX,
                .flowi4_tos = RT_TOS(ip4h->tos),
-               .flowi4_flags = FLOWI_FLAG_ANYSRC | FLOWI_FLAG_VRFSRC,
+               .flowi4_flags = FLOWI_FLAG_ANYSRC | FLOWI_FLAG_VRFSRC |
+                               FLOWI_FLAG_SKIP_NH_OIF,
                .daddr = ip4h->daddr,
        };
 
index acd6a096250e65e149db68d18b22d8dd320b6b39..9b85db85f13cfc2c11713da810260d4da554bde3 100644 (file)
@@ -35,6 +35,7 @@ struct flowi_common {
 #define FLOWI_FLAG_ANYSRC              0x01
 #define FLOWI_FLAG_KNOWN_NH            0x02
 #define FLOWI_FLAG_VRFSRC              0x04
+#define FLOWI_FLAG_SKIP_NH_OIF         0x08
        __u32   flowic_secid;
        struct flowi_tunnel flowic_tun_key;
 };
index 063d30474cf66077a7491ac8efbf4d400070c49e..aaf9700fc9e5f8279a172a7ee447cf4f9b5b6ffe 100644 (file)
@@ -275,7 +275,8 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt,
             struct nl_info *info, struct mx6_config *mxc);
 int fib6_del(struct rt6_info *rt, struct nl_info *info);
 
-void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info);
+void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info,
+                    unsigned int flags);
 
 void fib6_run_gc(unsigned long expires, struct net *net, bool force);
 
index cc61cb95f059152bc8cc58c0a2cacb2d9099e103..f46af256880cd9ff0f9fccc503d7cdc83ef3cbd3 100644 (file)
@@ -255,7 +255,7 @@ static inline void ip_route_connect_init(struct flowi4 *fl4, __be32 dst, __be32
                flow_flags |= FLOWI_FLAG_ANYSRC;
 
        if (netif_index_is_vrf(sock_net(sk), oif))
-               flow_flags |= FLOWI_FLAG_VRFSRC;
+               flow_flags |= FLOWI_FLAG_VRFSRC | FLOWI_FLAG_SKIP_NH_OIF;
 
        flowi4_init_output(fl4, oif, sk->sk_mark, tos, RT_SCOPE_UNIVERSE,
                           protocol, flow_flags, dst, src, dport, sport);
index 17e55dfecbe2a133a2a0e02d363b583a0334aecc..e07f551a863c89705fcbd348f2ac2eb73fd002fe 100644 (file)
@@ -317,6 +317,9 @@ static int clip_constructor(struct neighbour *neigh)
 
 static int clip_encap(struct atm_vcc *vcc, int mode)
 {
+       if (!CLIP_VCC(vcc))
+               return -EBADFD;
+
        CLIP_VCC(vcc)->encap = mode;
        return 0;
 }
index 26d6ffb6d23cdf4fff4150cb5f43ec35f5081fd4..6c2af797f2f92b93cf4ea28d1d5deee4e725f757 100644 (file)
@@ -1426,7 +1426,7 @@ found:
                            nh->nh_flags & RTNH_F_LINKDOWN &&
                            !(fib_flags & FIB_LOOKUP_IGNORE_LINKSTATE))
                                continue;
-                       if (!(flp->flowi4_flags & FLOWI_FLAG_VRFSRC)) {
+                       if (!(flp->flowi4_flags & FLOWI_FLAG_SKIP_NH_OIF)) {
                                if (flp->flowi4_oif &&
                                    flp->flowi4_oif != nh->nh_oif)
                                        continue;
index c0a15e7f359fe54e4edcffca5d59acb418dad116..f7d1d5e19e955563178fcddb84c4ffe9abb66036 100644 (file)
@@ -1024,7 +1024,8 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
                if (netif_index_is_vrf(net, ipc.oif)) {
                        flowi4_init_output(fl4, ipc.oif, sk->sk_mark, tos,
                                           RT_SCOPE_UNIVERSE, sk->sk_protocol,
-                                          (flow_flags | FLOWI_FLAG_VRFSRC),
+                                          (flow_flags | FLOWI_FLAG_VRFSRC |
+                                           FLOWI_FLAG_SKIP_NH_OIF),
                                           faddr, saddr, dport,
                                           inet->inet_sport);
 
index bb919b28619fbfd7689d5479ca267ce03db89d71..c10a9ee684337782fa96b71302c0f05695711f36 100644 (file)
@@ -33,6 +33,8 @@ static struct dst_entry *__xfrm4_dst_lookup(struct net *net, struct flowi4 *fl4,
        if (saddr)
                fl4->saddr = saddr->a4;
 
+       fl4->flowi4_flags = FLOWI_FLAG_SKIP_NH_OIF;
+
        rt = __ip_route_output_key(net, fl4);
        if (!IS_ERR(rt))
                return &rt->dst;
index 8a9ec01f4d016a9af476959e8256fa459e025e86..7d2e0023c72dbe2e466b35ffb1c6f0c0446af6da 100644 (file)
@@ -851,7 +851,7 @@ add:
                *ins = rt;
                rt->rt6i_node = fn;
                atomic_inc(&rt->rt6i_ref);
-               inet6_rt_notify(RTM_NEWROUTE, rt, info);
+               inet6_rt_notify(RTM_NEWROUTE, rt, info, 0);
                info->nl_net->ipv6.rt6_stats->fib_rt_entries++;
 
                if (!(fn->fn_flags & RTN_RTINFO)) {
@@ -877,7 +877,7 @@ add:
                rt->rt6i_node = fn;
                rt->dst.rt6_next = iter->dst.rt6_next;
                atomic_inc(&rt->rt6i_ref);
-               inet6_rt_notify(RTM_NEWROUTE, rt, info);
+               inet6_rt_notify(RTM_NEWROUTE, rt, info, NLM_F_REPLACE);
                if (!(fn->fn_flags & RTN_RTINFO)) {
                        info->nl_net->ipv6.rt6_stats->fib_route_nodes++;
                        fn->fn_flags |= RTN_RTINFO;
@@ -1422,7 +1422,7 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp,
 
        fib6_purge_rt(rt, fn, net);
 
-       inet6_rt_notify(RTM_DELROUTE, rt, info);
+       inet6_rt_notify(RTM_DELROUTE, rt, info, 0);
        rt6_release(rt);
 }
 
index 26ea4793074004d0af1026bb378860b53baa0ad2..92b1aa38f121507b662e2c964423952bf995b81e 100644 (file)
@@ -586,20 +586,22 @@ int ip6_fragment(struct sock *sk, struct sk_buff *skb,
        frag_id = ipv6_select_ident(net, &ipv6_hdr(skb)->daddr,
                                    &ipv6_hdr(skb)->saddr);
 
+       hroom = LL_RESERVED_SPACE(rt->dst.dev);
        if (skb_has_frag_list(skb)) {
                int first_len = skb_pagelen(skb);
                struct sk_buff *frag2;
 
                if (first_len - hlen > mtu ||
                    ((first_len - hlen) & 7) ||
-                   skb_cloned(skb))
+                   skb_cloned(skb) ||
+                   skb_headroom(skb) < (hroom + sizeof(struct frag_hdr)))
                        goto slow_path;
 
                skb_walk_frags(skb, frag) {
                        /* Correct geometry. */
                        if (frag->len > mtu ||
                            ((frag->len & 7) && frag->next) ||
-                           skb_headroom(frag) < hlen)
+                           skb_headroom(frag) < (hlen + hroom + sizeof(struct frag_hdr)))
                                goto slow_path_clean;
 
                        /* Partially cloned skb? */
@@ -616,8 +618,6 @@ int ip6_fragment(struct sock *sk, struct sk_buff *skb,
 
                err = 0;
                offset = 0;
-               frag = skb_shinfo(skb)->frag_list;
-               skb_frag_list_init(skb);
                /* BUILD HEADER */
 
                *prevhdr = NEXTHDR_FRAGMENT;
@@ -625,8 +625,11 @@ int ip6_fragment(struct sock *sk, struct sk_buff *skb,
                if (!tmp_hdr) {
                        IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
                                      IPSTATS_MIB_FRAGFAILS);
-                       return -ENOMEM;
+                       err = -ENOMEM;
+                       goto fail;
                }
+               frag = skb_shinfo(skb)->frag_list;
+               skb_frag_list_init(skb);
 
                __skb_pull(skb, hlen);
                fh = (struct frag_hdr *)__skb_push(skb, sizeof(struct frag_hdr));
@@ -723,7 +726,6 @@ slow_path:
         */
 
        *prevhdr = NEXTHDR_FRAGMENT;
-       hroom = LL_RESERVED_SPACE(rt->dst.dev);
        troom = rt->dst.dev->needed_tailroom;
 
        /*
index 3d3c1b294725af9c834546b7abfcb154806c9c5d..d5fa50297f807839c308273b7c9115a6842c5764 100644 (file)
@@ -3304,7 +3304,8 @@ errout:
        return err;
 }
 
-void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info)
+void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info,
+                    unsigned int nlm_flags)
 {
        struct sk_buff *skb;
        struct net *net = info->nl_net;
@@ -3319,7 +3320,7 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info)
                goto errout;
 
        err = rt6_fill_node(net, skb, rt, NULL, NULL, 0,
-                               event, info->portid, seq, 0, 0, 0);
+                               event, info->portid, seq, 0, 0, nlm_flags);
        if (err < 0) {
                /* -EMSGSIZE implies BUG in rt6_nlmsg_size() */
                WARN_ON(err == -EMSGSIZE);
index e8e524ad8a01cb3e62b531cf13659784f2f123ef..002a755fa07ea8c6c71c762716a5be8700c0a36c 100644 (file)
@@ -275,13 +275,15 @@ static int ovs_ct_helper(struct sk_buff *skb, u16 proto)
        case NFPROTO_IPV6: {
                u8 nexthdr = ipv6_hdr(skb)->nexthdr;
                __be16 frag_off;
+               int ofs;
 
-               protoff = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr),
-                                          &nexthdr, &frag_off);
-               if (protoff < 0 || (frag_off & htons(~0x7)) != 0) {
+               ofs = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &nexthdr,
+                                      &frag_off);
+               if (ofs < 0 || (frag_off & htons(~0x7)) != 0) {
                        pr_debug("proto header not found\n");
                        return NF_ACCEPT;
                }
+               protoff = ofs;
                break;
        }
        default: