]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetoot...
authorDavid S. Miller <davem@davemloft.net>
Mon, 18 May 2015 20:15:31 +0000 (16:15 -0400)
committerDavid S. Miller <davem@davemloft.net>
Mon, 18 May 2015 20:15:31 +0000 (16:15 -0400)
Johan Hedberg says:

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

A couple more Bluetooth updates for 4.1:

- New USB IDs for ath3k & btusb
- Fix for remote name resolving during device discovery

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

Signed-off-by: David S. Miller <davem@davemloft.net>
21 files changed:
drivers/net/bonding/bond_options.c
drivers/net/ethernet/cadence/macb.c
drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
drivers/net/ethernet/rocker/rocker.c
drivers/net/phy/phy.c
include/linux/rhashtable.h
include/uapi/linux/netfilter/nf_conntrack_tcp.h
include/uapi/linux/rtnetlink.h
lib/rhashtable.c
net/8021q/vlan.c
net/core/rtnetlink.c
net/ipv4/fib_trie.c
net/ipv4/tcp_minisocks.c
net/ipv6/ip6_output.c
net/ipv6/tcp_ipv6.c
net/netfilter/Kconfig
net/netfilter/ipvs/ip_vs_ctl.c
net/netfilter/nf_conntrack_proto_tcp.c
net/netfilter/nf_tables_api.c
net/netlink/af_netlink.c
net/switchdev/switchdev.c

index 4df28943d2229035166d2bb4a72ec11c8f9671c5..e8d3c1d35453d1e182cd4b82388978f580abe946 100644 (file)
@@ -624,7 +624,7 @@ int __bond_opt_set(struct bonding *bond,
 out:
        if (ret)
                bond_opt_error_interpret(bond, opt, ret, val);
-       else
+       else if (bond->dev->reg_state == NETREG_REGISTERED)
                call_netdevice_notifiers(NETDEV_CHANGEINFODATA, bond->dev);
 
        return ret;
index 61aa570aad9a1b821613de323ef54701010fce53..5f10dfc631d794ef13861b706e5c11445c9243b8 100644 (file)
@@ -1037,6 +1037,12 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
                 * add that if/when we get our hands on a full-blown MII PHY.
                 */
 
+               /* There is a hardware issue under heavy load where DMA can
+                * stop, this causes endless "used buffer descriptor read"
+                * interrupts but it can be cleared by re-enabling RX. See
+                * the at91 manual, section 41.3.1 or the Zynq manual
+                * section 16.7.4 for details.
+                */
                if (status & MACB_BIT(RXUBR)) {
                        ctrl = macb_readl(bp, NCR);
                        macb_writel(bp, NCR, ctrl & ~MACB_BIT(RE));
index 92fce1b985589b993e3feccbf528e57c3a91fdb0..bafe2180cf0c413c4d971f8043e401a018dc8100 100644 (file)
@@ -3187,7 +3187,7 @@ int mlx4_SW2HW_CQ_wrapper(struct mlx4_dev *dev, int slave,
        int cqn = vhcr->in_modifier;
        struct mlx4_cq_context *cqc = inbox->buf;
        int mtt_base = cq_get_mtt_addr(cqc) / dev->caps.mtt_entry_sz;
-       struct res_cq *cq;
+       struct res_cq *cq = NULL;
        struct res_mtt *mtt;
 
        err = cq_res_start_move_to(dev, slave, cqn, RES_CQ_HW, &cq);
@@ -3223,7 +3223,7 @@ int mlx4_HW2SW_CQ_wrapper(struct mlx4_dev *dev, int slave,
 {
        int err;
        int cqn = vhcr->in_modifier;
-       struct res_cq *cq;
+       struct res_cq *cq = NULL;
 
        err = cq_res_start_move_to(dev, slave, cqn, RES_CQ_ALLOCATED, &cq);
        if (err)
@@ -3362,7 +3362,7 @@ int mlx4_SW2HW_SRQ_wrapper(struct mlx4_dev *dev, int slave,
        int err;
        int srqn = vhcr->in_modifier;
        struct res_mtt *mtt;
-       struct res_srq *srq;
+       struct res_srq *srq = NULL;
        struct mlx4_srq_context *srqc = inbox->buf;
        int mtt_base = srq_get_mtt_addr(srqc) / dev->caps.mtt_entry_sz;
 
@@ -3406,7 +3406,7 @@ int mlx4_HW2SW_SRQ_wrapper(struct mlx4_dev *dev, int slave,
 {
        int err;
        int srqn = vhcr->in_modifier;
-       struct res_srq *srq;
+       struct res_srq *srq = NULL;
 
        err = srq_res_start_move_to(dev, slave, srqn, RES_SRQ_ALLOCATED, &srq);
        if (err)
index ec251531bd9f8ecd1e64295b4f1f5c35fe475b79..cf98cc9bbc8dc9d57545bbbe25592f6878fcf324 100644 (file)
@@ -2921,10 +2921,11 @@ static int rocker_port_ipv4_resolve(struct rocker_port *rocker_port,
        struct neighbour *n = __ipv4_neigh_lookup(dev, (__force u32)ip_addr);
        int err = 0;
 
-       if (!n)
+       if (!n) {
                n = neigh_create(&arp_tbl, &ip_addr, dev);
-       if (!n)
-               return -ENOMEM;
+               if (IS_ERR(n))
+                       return IS_ERR(n);
+       }
 
        /* If the neigh is already resolved, then go ahead and
         * install the entry, otherwise start the ARP process to
@@ -2936,6 +2937,7 @@ static int rocker_port_ipv4_resolve(struct rocker_port *rocker_port,
        else
                neigh_event_send(n, NULL);
 
+       neigh_release(n);
        return err;
 }
 
index 52cd8db2c57daad2767dec72149f4cdabbcf6917..710696d1af97ea464b9035c10a08d64c1377e093 100644 (file)
@@ -465,7 +465,7 @@ int phy_start_aneg(struct phy_device *phydev)
        if (err < 0)
                goto out_unlock;
 
-       if (phydev->state != PHY_HALTED) {
+       if (phydev->state != PHY_HALTED && phydev->state != PHY_RESUMING) {
                if (AUTONEG_ENABLE == phydev->autoneg) {
                        phydev->state = PHY_AN;
                        phydev->link_timeout = PHY_AN_TIMEOUT;
@@ -1053,13 +1053,14 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable)
 {
        /* According to 802.3az,the EEE is supported only in full duplex-mode.
         * Also EEE feature is active when core is operating with MII, GMII
-        * or RGMII. Internal PHYs are also allowed to proceed and should
-        * return an error if they do not support EEE.
+        * or RGMII (all kinds). Internal PHYs are also allowed to proceed and
+        * should return an error if they do not support EEE.
         */
        if ((phydev->duplex == DUPLEX_FULL) &&
            ((phydev->interface == PHY_INTERFACE_MODE_MII) ||
            (phydev->interface == PHY_INTERFACE_MODE_GMII) ||
-           (phydev->interface == PHY_INTERFACE_MODE_RGMII) ||
+           (phydev->interface >= PHY_INTERFACE_MODE_RGMII &&
+            phydev->interface <= PHY_INTERFACE_MODE_RGMII_TXID) ||
             phy_is_internal(phydev))) {
                int eee_lp, eee_cap, eee_adv;
                u32 lp, cap, adv;
index dbcbcc59aa92e77de6c1c6065b403c0fa7d0dd15..843ceca9a21e5f1327fa5c82fa5f3089c5ebab23 100644 (file)
@@ -17,6 +17,7 @@
 #ifndef _LINUX_RHASHTABLE_H
 #define _LINUX_RHASHTABLE_H
 
+#include <linux/atomic.h>
 #include <linux/compiler.h>
 #include <linux/errno.h>
 #include <linux/jhash.h>
@@ -100,6 +101,7 @@ struct rhashtable;
  * @key_len: Length of key
  * @key_offset: Offset of key in struct to be hashed
  * @head_offset: Offset of rhash_head in struct to be hashed
+ * @insecure_max_entries: Maximum number of entries (may be exceeded)
  * @max_size: Maximum size while expanding
  * @min_size: Minimum size while shrinking
  * @nulls_base: Base value to generate nulls marker
@@ -115,6 +117,7 @@ struct rhashtable_params {
        size_t                  key_len;
        size_t                  key_offset;
        size_t                  head_offset;
+       unsigned int            insecure_max_entries;
        unsigned int            max_size;
        unsigned int            min_size;
        u32                     nulls_base;
@@ -286,6 +289,18 @@ static inline bool rht_grow_above_100(const struct rhashtable *ht,
                (!ht->p.max_size || tbl->size < ht->p.max_size);
 }
 
+/**
+ * rht_grow_above_max - returns true if table is above maximum
+ * @ht:                hash table
+ * @tbl:       current table
+ */
+static inline bool rht_grow_above_max(const struct rhashtable *ht,
+                                     const struct bucket_table *tbl)
+{
+       return ht->p.insecure_max_entries &&
+              atomic_read(&ht->nelems) >= ht->p.insecure_max_entries;
+}
+
 /* The bucket lock is selected based on the hash and protects mutations
  * on a group of hash buckets.
  *
@@ -589,6 +604,10 @@ static inline int __rhashtable_insert_fast(
                goto out;
        }
 
+       err = -E2BIG;
+       if (unlikely(rht_grow_above_max(ht, tbl)))
+               goto out;
+
        if (unlikely(rht_grow_above_100(ht, tbl))) {
 slow_path:
                spin_unlock_bh(lock);
index 9993a421201c231af01d85ef7c1d355745526565..ef9f80f0f529d156a906b461cc7595c4c83358a6 100644 (file)
@@ -42,6 +42,9 @@ enum tcp_conntrack {
 /* The field td_maxack has been set */
 #define IP_CT_TCP_FLAG_MAXACK_SET              0x20
 
+/* Marks possibility for expected RFC5961 challenge ACK */
+#define IP_CT_EXP_CHALLENGE_ACK                0x40
+
 struct nf_ct_tcp_flags {
        __u8 flags;
        __u8 mask;
index 974db03f7b1a2d9ddf96d0b34a409f8356e94d1a..17fb02f488da88efdcd071258a487ab563251f37 100644 (file)
@@ -337,7 +337,7 @@ struct rtnexthop {
 #define RTNH_F_DEAD            1       /* Nexthop is dead (used by multipath)  */
 #define RTNH_F_PERVASIVE       2       /* Do recursive gateway lookup  */
 #define RTNH_F_ONLINK          4       /* Gateway is forced on link    */
-#define RTNH_F_EXTERNAL                8       /* Route installed externally   */
+#define RTNH_F_OFFLOAD         8       /* offloaded route */
 
 /* Macros to handle hexthops */
 
index b28df4019adedfe182d5c719da62b6bf05c031fe..4396434e471536b4772ef06efcb983f87c580889 100644 (file)
@@ -14,6 +14,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/atomic.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/log2.h>
@@ -446,6 +447,10 @@ int rhashtable_insert_slow(struct rhashtable *ht, const void *key,
        if (key && rhashtable_lookup_fast(ht, key, ht->p))
                goto exit;
 
+       err = -E2BIG;
+       if (unlikely(rht_grow_above_max(ht, tbl)))
+               goto exit;
+
        err = -EAGAIN;
        if (rhashtable_check_elasticity(ht, tbl, hash) ||
            rht_grow_above_100(ht, tbl))
@@ -738,6 +743,12 @@ int rhashtable_init(struct rhashtable *ht,
        if (params->max_size)
                ht->p.max_size = rounddown_pow_of_two(params->max_size);
 
+       if (params->insecure_max_entries)
+               ht->p.insecure_max_entries =
+                       rounddown_pow_of_two(params->insecure_max_entries);
+       else
+               ht->p.insecure_max_entries = ht->p.max_size * 2;
+
        ht->p.min_size = max(ht->p.min_size, HASH_MIN_SIZE);
 
        /* The maximum (not average) chain length grows with the
index 98a30a5b866472b7421f5394636934bc23ec7f94..59555f0f8fc85b039cab18350906ae3c86a477af 100644 (file)
@@ -443,7 +443,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
        case NETDEV_UP:
                /* Put all VLANs for this dev in the up state too.  */
                vlan_group_for_each_dev(grp, i, vlandev) {
-                       flgs = vlandev->flags;
+                       flgs = dev_get_flags(vlandev);
                        if (flgs & IFF_UP)
                                continue;
 
index 666e0928ba404b85cf210749e505a2c205e5ee3f..8de36824018de4da2369fb02234692c4e0260b27 100644 (file)
@@ -2416,6 +2416,9 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned int change,
 {
        struct sk_buff *skb;
 
+       if (dev->reg_state != NETREG_REGISTERED)
+               return;
+
        skb = rtmsg_ifinfo_build_skb(type, dev, change, flags);
        if (skb)
                rtmsg_ifinfo_send(skb, dev, flags);
index e13fcc602da20ee44dfd505ab1115bbcc0e13375..64c2076ced54c5c639518e30d1d23acf989d1167 100644 (file)
@@ -1764,7 +1764,7 @@ void fib_table_flush_external(struct fib_table *tb)
                        /* record local slen */
                        slen = fa->fa_slen;
 
-                       if (!fi || !(fi->fib_flags & RTNH_F_EXTERNAL))
+                       if (!fi || !(fi->fib_flags & RTNH_F_OFFLOAD))
                                continue;
 
                        netdev_switch_fib_ipv4_del(n->key,
index e5d7649136fcb31ca70b097dcbd9873df07e7417..b5732a54f2ad60f5a528535f7754d644527d4d81 100644 (file)
@@ -300,7 +300,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo)
                        tw->tw_v6_daddr = sk->sk_v6_daddr;
                        tw->tw_v6_rcv_saddr = sk->sk_v6_rcv_saddr;
                        tw->tw_tclass = np->tclass;
-                       tw->tw_flowlabel = np->flow_label >> 12;
+                       tw->tw_flowlabel = be32_to_cpu(np->flow_label & IPV6_FLOWLABEL_MASK);
                        tw->tw_ipv6only = sk->sk_ipv6only;
                }
 #endif
index c21777565c58cabd7649cc48b790ff21c88498b5..bc09cb97b8401011c112afe469fd231382387622 100644 (file)
@@ -1300,8 +1300,10 @@ static int __ip6_append_data(struct sock *sk,
 
        /* If this is the first and only packet and device
         * supports checksum offloading, let's use it.
+        * Use transhdrlen, same as IPv4, because partial
+        * sums only work when transhdrlen is set.
         */
-       if (!skb && sk->sk_protocol == IPPROTO_UDP &&
+       if (transhdrlen && sk->sk_protocol == IPPROTO_UDP &&
            length + fragheaderlen < mtu &&
            rt->dst.dev->features & NETIF_F_V6_CSUM &&
            !exthdrlen)
index b6575d6655681e8e84993a5db929c7309d47d4d3..3adffb300238ebdaf729871bafbb348e82fbde56 100644 (file)
@@ -914,7 +914,7 @@ static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb)
                        tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale,
                        tcp_time_stamp + tcptw->tw_ts_offset,
                        tcptw->tw_ts_recent, tw->tw_bound_dev_if, tcp_twsk_md5_key(tcptw),
-                       tw->tw_tclass, (tw->tw_flowlabel << 12));
+                       tw->tw_tclass, cpu_to_be32(tw->tw_flowlabel));
 
        inet_twsk_put(tw);
 }
index f70e34a68f702ab39c43e27d4b8e8127b49525f6..a0f3e6a3c7d18f344d3321a83b5c11d1988d5d3d 100644 (file)
@@ -863,6 +863,7 @@ config NETFILTER_XT_TARGET_TPROXY
        depends on NETFILTER_XTABLES
        depends on NETFILTER_ADVANCED
        depends on (IPV6 || IPV6=n)
+       depends on (IP6_NF_IPTABLES || IP6_NF_IPTABLES=n)
        depends on IP_NF_MANGLE
        select NF_DEFRAG_IPV4
        select NF_DEFRAG_IPV6 if IP6_NF_IPTABLES
@@ -1356,6 +1357,7 @@ config NETFILTER_XT_MATCH_SOCKET
        depends on NETFILTER_ADVANCED
        depends on !NF_CONNTRACK || NF_CONNTRACK
        depends on (IPV6 || IPV6=n)
+       depends on (IP6_NF_IPTABLES || IP6_NF_IPTABLES=n)
        select NF_DEFRAG_IPV4
        select NF_DEFRAG_IPV6 if IP6_NF_IPTABLES
        help
index 49532672f66dad0c3bae1b923993b0d1f518b25b..285eae3a145483c48c00493651a46a5d81656845 100644 (file)
@@ -3823,6 +3823,9 @@ static void __net_exit ip_vs_control_net_cleanup_sysctl(struct net *net)
        cancel_work_sync(&ipvs->defense_work.work);
        unregister_net_sysctl_table(ipvs->sysctl_hdr);
        ip_vs_stop_estimator(net, &ipvs->tot_stats);
+
+       if (!net_eq(net, &init_net))
+               kfree(ipvs->sysctl_tbl);
 }
 
 #else
index 5caa0c41bf26c3e6a2542f0dd50ac6f029ed8a84..70383de7205460a8ebdadd7fd1ba615fc7681296 100644 (file)
@@ -202,7 +202,7 @@ static const u8 tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {
  *     sES -> sES      :-)
  *     sFW -> sCW      Normal close request answered by ACK.
  *     sCW -> sCW
- *     sLA -> sTW      Last ACK detected.
+ *     sLA -> sTW      Last ACK detected (RFC5961 challenged)
  *     sTW -> sTW      Retransmitted last ACK. Remain in the same state.
  *     sCL -> sCL
  */
@@ -261,7 +261,7 @@ static const u8 tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {
  *     sES -> sES      :-)
  *     sFW -> sCW      Normal close request answered by ACK.
  *     sCW -> sCW
- *     sLA -> sTW      Last ACK detected.
+ *     sLA -> sTW      Last ACK detected (RFC5961 challenged)
  *     sTW -> sTW      Retransmitted last ACK.
  *     sCL -> sCL
  */
@@ -906,6 +906,7 @@ static int tcp_packet(struct nf_conn *ct,
                                        1 : ct->proto.tcp.last_win;
                        ct->proto.tcp.seen[ct->proto.tcp.last_dir].td_scale =
                                ct->proto.tcp.last_wscale;
+                       ct->proto.tcp.last_flags &= ~IP_CT_EXP_CHALLENGE_ACK;
                        ct->proto.tcp.seen[ct->proto.tcp.last_dir].flags =
                                ct->proto.tcp.last_flags;
                        memset(&ct->proto.tcp.seen[dir], 0,
@@ -923,7 +924,9 @@ static int tcp_packet(struct nf_conn *ct,
                 * may be in sync but we are not. In that case, we annotate
                 * the TCP options and let the packet go through. If it is a
                 * valid SYN packet, the server will reply with a SYN/ACK, and
-                * then we'll get in sync. Otherwise, the server ignores it. */
+                * then we'll get in sync. Otherwise, the server potentially
+                * responds with a challenge ACK if implementing RFC5961.
+                */
                if (index == TCP_SYN_SET && dir == IP_CT_DIR_ORIGINAL) {
                        struct ip_ct_tcp_state seen = {};
 
@@ -939,6 +942,13 @@ static int tcp_packet(struct nf_conn *ct,
                                ct->proto.tcp.last_flags |=
                                        IP_CT_TCP_FLAG_SACK_PERM;
                        }
+                       /* Mark the potential for RFC5961 challenge ACK,
+                        * this pose a special problem for LAST_ACK state
+                        * as ACK is intrepretated as ACKing last FIN.
+                        */
+                       if (old_state == TCP_CONNTRACK_LAST_ACK)
+                               ct->proto.tcp.last_flags |=
+                                       IP_CT_EXP_CHALLENGE_ACK;
                }
                spin_unlock_bh(&ct->lock);
                if (LOG_INVALID(net, IPPROTO_TCP))
@@ -970,6 +980,25 @@ static int tcp_packet(struct nf_conn *ct,
                        nf_log_packet(net, pf, 0, skb, NULL, NULL, NULL,
                                  "nf_ct_tcp: invalid state ");
                return -NF_ACCEPT;
+       case TCP_CONNTRACK_TIME_WAIT:
+               /* RFC5961 compliance cause stack to send "challenge-ACK"
+                * e.g. in response to spurious SYNs.  Conntrack MUST
+                * not believe this ACK is acking last FIN.
+                */
+               if (old_state == TCP_CONNTRACK_LAST_ACK &&
+                   index == TCP_ACK_SET &&
+                   ct->proto.tcp.last_dir != dir &&
+                   ct->proto.tcp.last_index == TCP_SYN_SET &&
+                   (ct->proto.tcp.last_flags & IP_CT_EXP_CHALLENGE_ACK)) {
+                       /* Detected RFC5961 challenge ACK */
+                       ct->proto.tcp.last_flags &= ~IP_CT_EXP_CHALLENGE_ACK;
+                       spin_unlock_bh(&ct->lock);
+                       if (LOG_INVALID(net, IPPROTO_TCP))
+                               nf_log_packet(net, pf, 0, skb, NULL, NULL, NULL,
+                                     "nf_ct_tcp: challenge-ACK ignored ");
+                       return NF_ACCEPT; /* Don't change state */
+               }
+               break;
        case TCP_CONNTRACK_CLOSE:
                if (index == TCP_RST_SET
                    && (ct->proto.tcp.seen[!dir].flags & IP_CT_TCP_FLAG_MAXACK_SET)
index ad9d11fb29fd208cd44d67e786b7977afc9e51e7..34ded09317e715cc94b80ce8d918006bbe1f714b 100644 (file)
@@ -4472,9 +4472,9 @@ EXPORT_SYMBOL_GPL(nft_data_init);
  */
 void nft_data_uninit(const struct nft_data *data, enum nft_data_types type)
 {
-       switch (type) {
-       case NFT_DATA_VALUE:
+       if (type < NFT_DATA_VERDICT)
                return;
+       switch (type) {
        case NFT_DATA_VERDICT:
                return nft_verdict_uninit(data);
        default:
index daa0b818174bdc2c7b5e15e5e0dbd6b287014ba6..bf6e76643f7876d8dee4df261baf077aad837be3 100644 (file)
@@ -89,7 +89,7 @@ static inline int netlink_is_kernel(struct sock *sk)
        return nlk_sk(sk)->flags & NETLINK_KERNEL_SOCKET;
 }
 
-struct netlink_table *nl_table;
+struct netlink_table *nl_table __read_mostly;
 EXPORT_SYMBOL_GPL(nl_table);
 
 static DECLARE_WAIT_QUEUE_HEAD(nl_table_wait);
@@ -1081,6 +1081,7 @@ static int netlink_insert(struct sock *sk, u32 portid)
        if (err) {
                if (err == -EEXIST)
                        err = -EADDRINUSE;
+               nlk_sk(sk)->portid = 0;
                sock_put(sk);
        }
 
index 46568b85c3339f57a0d6835e82eff4b67c3ba326..055453d486683ec19433961db220292e4f60571d 100644 (file)
@@ -338,7 +338,7 @@ int netdev_switch_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi,
                                              fi, tos, type, nlflags,
                                              tb_id);
                if (!err)
-                       fi->fib_flags |= RTNH_F_EXTERNAL;
+                       fi->fib_flags |= RTNH_F_OFFLOAD;
        }
 
        return err;
@@ -364,7 +364,7 @@ int netdev_switch_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi,
        const struct swdev_ops *ops;
        int err = 0;
 
-       if (!(fi->fib_flags & RTNH_F_EXTERNAL))
+       if (!(fi->fib_flags & RTNH_F_OFFLOAD))
                return 0;
 
        dev = netdev_switch_get_dev_by_nhs(fi);
@@ -376,7 +376,7 @@ int netdev_switch_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi,
                err = ops->swdev_fib_ipv4_del(dev, htonl(dst), dst_len,
                                              fi, tos, type, tb_id);
                if (!err)
-                       fi->fib_flags &= ~RTNH_F_EXTERNAL;
+                       fi->fib_flags &= ~RTNH_F_OFFLOAD;
        }
 
        return err;