Changeset 32623


Ignore:
Timestamp:
Jul 9, 2017, 12:18:42 PM (11 days ago)
Author:
brainslayer
Message:

merge QCA SFE kernel support

Location:
src/linux/universal
Files:
36 edited

Legend:

Unmodified
Added
Removed
  • src/linux/universal/linux-3.10/include/linux/if_bridge.h

    r21644 r32623  
    1818
    1919extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *));
     20extern void br_dev_update_stats(struct net_device *dev, struct rtnl_link_stats64 *nlstats);
    2021
    2122typedef int br_should_route_hook_t(struct sk_buff *skb);
  • src/linux/universal/linux-3.10/include/linux/skbuff.h

    r28039 r32623  
    498498        __u8                    no_fcs:1;
    499499        __u8                    head_frag:1;
     500        __u8                    fast_forwarded:1;
    500501        /* Encapsulation protocol and NIC drivers should use
    501502         * this flag to indicate to each other if the skb contains
  • src/linux/universal/linux-3.10/include/net/netfilter/nf_conntrack_ecache.h

    r21644 r32623  
    6565};
    6666
    67 struct nf_ct_event_notifier {
    68         int (*fcn)(unsigned int events, struct nf_ct_event *item);
    69 };
    70 
    71 extern int nf_conntrack_register_notifier(struct net *net, struct nf_ct_event_notifier *nb);
    72 extern void nf_conntrack_unregister_notifier(struct net *net, struct nf_ct_event_notifier *nb);
     67extern int nf_conntrack_register_notifier(struct net *net, struct notifier_block *nb);
     68extern int nf_conntrack_unregister_notifier(struct net *net, struct notifier_block *nb);
    7369
    7470extern void nf_ct_deliver_cached_events(struct nf_conn *ct);
     
    7773nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct)
    7874{
    79         struct net *net = nf_ct_net(ct);
    80         struct nf_conntrack_ecache *e;
    81 
    82         if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb) && !rcu_access_pointer(net->ct.nf_conntrack_event_cb_2))
    83                 return;
     75        struct nf_conntrack_ecache *e;
    8476
    8577        e = nf_ct_ecache_find(ct);
     
    9688                              int report)
    9789{
    98         int ret = 0;
     90        struct nf_conntrack_ecache *e;
     91
    9992        struct net *net = nf_ct_net(ct);
    100         struct nf_ct_event_notifier *notify;
    101         struct nf_ct_event_notifier *notify_2;
    102         struct nf_conntrack_ecache *e;
    103 
    104         rcu_read_lock();
    105         /* Incredibly nasty duplication in order to hack second event */
    106         notify = rcu_dereference(net->ct.nf_conntrack_event_cb);
    107         notify_2 = rcu_dereference(net->ct.nf_conntrack_event_cb_2);
    108         if ((notify == NULL) && (notify_2 == NULL))
    109                 goto out_unlock;
    11093
    11194        e = nf_ct_ecache_find(ct);
    11295        if (e == NULL)
    113                 goto out_unlock;
     96                return 0;
    11497
    11598        if (nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct)) {
     
    123106
    124107                if (!((eventmask | missed) & e->ctmask))
    125                         goto out_unlock;
    126 
    127                 ret = min( notify ? notify->fcn(eventmask | missed, &item) : 0,
    128                            notify_2 ? notify_2->fcn(eventmask | missed, &item) : 0 );
    129                 if (unlikely(ret < 0 || missed)) {
    130                         spin_lock_bh(&ct->lock);
    131                         if (ret < 0) {
    132                                 /* This is a destroy event that has been
    133                                  * triggered by a process, we store the PORTID
    134                                  * to include it in the retransmission. */
    135                                 if (eventmask & (1 << IPCT_DESTROY) &&
    136                                     e->portid == 0 && portid != 0)
    137                                         e->portid = portid;
    138                                 else
    139                                         e->missed |= eventmask;
    140                         } else
    141                                 e->missed &= ~missed;
    142                         spin_unlock_bh(&ct->lock);
    143                 }
    144         }
    145 out_unlock:
    146         rcu_read_unlock();
    147         return ret;
     108                        return 0;
     109
     110                atomic_notifier_call_chain(&net->ct.nf_conntrack_chain, eventmask | missed, &item);
     111        }
     112
     113        return 0;
    148114}
    149115
  • src/linux/universal/linux-3.10/include/net/netns/conntrack.h

    r21644 r32623  
    7474        struct hlist_nulls_head tmpl;
    7575        struct ip_conntrack_stat __percpu *stat;
    76         struct nf_ct_event_notifier __rcu *nf_conntrack_event_cb;
    77         struct nf_ct_event_notifier __rcu *nf_conntrack_event_cb_2;
     76        struct atomic_notifier_head nf_conntrack_chain;
    7877        struct nf_exp_event_notifier __rcu *nf_expect_event_cb;
    7978        int                     sysctl_events;
  • src/linux/universal/linux-3.10/net/bridge/br_if.c

    r23047 r32623  
    468468
    469469}
     470
     471/* Update bridge statistics for bridge packets processed by offload engines */
     472void br_dev_update_stats(struct net_device *dev, struct rtnl_link_stats64 *nlstats)
     473{
     474        struct net_bridge *br;
     475        struct pcpu_sw_netstats *stats;
     476
     477        /*
     478         * Is this a bridge?
     479         */
     480        if (!(dev->priv_flags & IFF_EBRIDGE))
     481                return;
     482
     483        br = netdev_priv(dev);
     484        stats = per_cpu_ptr(br->stats, 0);
     485
     486        u64_stats_update_begin(&stats->syncp);
     487        stats->rx_packets += nlstats->rx_packets;
     488        stats->rx_bytes += nlstats->rx_bytes;
     489        stats->tx_packets += nlstats->tx_packets;
     490        stats->tx_bytes += nlstats->tx_bytes;
     491        u64_stats_update_end(&stats->syncp);
     492}
     493EXPORT_SYMBOL_GPL(br_dev_update_stats);
  • src/linux/universal/linux-3.10/net/core/dev.c

    r32550 r32623  
    26092609                }
    26102610
     2611        if (!skb->fast_forwarded) {
    26112612#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
    2612                 if (!list_empty(&ptype_all) &&
     2613        if (!list_empty(&ptype_all) &&
    26132614                                        !(skb->imq_flags & IMQ_F_ENQUEUE))
    26142615#else
     
    26162617#endif
    26172618                        dev_queue_xmit_nit(skb, dev);
     2619        }
    26182620
    26192621#ifdef CONFIG_ETHERNET_PACKET_MANGLE
     
    26422644                nskb->next = NULL;
    26432645
     2646        if (!skb->fast_forwarded) {
    26442647                if (!list_empty(&ptype_all))
    26452648                        dev_queue_xmit_nit(nskb, dev);
    2646 
     2649        }
    26472650#ifdef CONFIG_ETHERNET_PACKET_MANGLE
    26482651                if (!dev->eth_mangle_tx ||
     
    34703473EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister);
    34713474
     3475int (*fast_nat_recv)(struct sk_buff *skb) __rcu __read_mostly;
     3476EXPORT_SYMBOL_GPL(fast_nat_recv);
     3477
    34723478/*
    34733479 * Limit the use of PFMEMALLOC reserves to those protocols that implement
     
    34973503        int ret = NET_RX_DROP;
    34983504        __be16 type;
     3505        int (*fast_recv)(struct sk_buff *skb);
    34993506
    35003507        net_timestamp_check(!netdev_tstamp_prequeue, skb);
     
    35253532                if (unlikely(!skb))
    35263533                        goto out;
     3534        }
     3535
     3536        fast_recv = rcu_dereference(fast_nat_recv);
     3537        if (fast_recv && fast_recv(skb)) {
     3538                ret = NET_RX_SUCCESS;
     3539                goto out;
    35273540        }
    35283541
  • src/linux/universal/linux-3.10/net/netfilter/nf_conntrack_core.c

    r29196 r32623  
    16971697        if (ret < 0)
    16981698                goto err_proto;
     1699        ATOMIC_INIT_NOTIFIER_HEAD(&net->ct.nf_conntrack_chain);
    16991700        return 0;
    17001701
  • src/linux/universal/linux-3.10/net/netfilter/nf_conntrack_ecache.c

    r21644 r32623  
    1919#include <linux/err.h>
    2020#include <linux/percpu.h>
     21#include <linux/notifier.h>
    2122#include <linux/kernel.h>
    2223#include <linux/netdevice.h>
     
    3435void nf_ct_deliver_cached_events(struct nf_conn *ct)
    3536{
    36         struct net *net = nf_ct_net(ct);
    3737        unsigned long events, missed;
    3838        /* Incredibly nasty duplication in order to hack second event */
    39         struct nf_ct_event_notifier *notify;
    40         struct nf_ct_event_notifier *notify_2;
    4139        struct nf_conntrack_ecache *e;
    4240        struct nf_ct_event item;
    4341        int ret;
    4442
    45         rcu_read_lock();
    46         notify = rcu_dereference(net->ct.nf_conntrack_event_cb);
    47         notify_2 = rcu_dereference(net->ct.nf_conntrack_event_cb_2);
    48         if ( (notify == NULL) && (notify_2 == NULL) )
    49                 goto out_unlock;
     43        struct net *net = nf_ct_net(ct);
    5044
    5145        e = nf_ct_ecache_find(ct);
    5246        if (e == NULL)
    53                 goto out_unlock;
     47                return;
    5448
    5549        events = xchg(&e->cache, 0);
    5650
    5751        if (!nf_ct_is_confirmed(ct) || nf_ct_is_dying(ct) || !events)
    58                 goto out_unlock;
     52                return;
    5953
    6054        /* We make a copy of the missed event cache without taking
     
    6458
    6559        if (!((events | missed) & e->ctmask))
    66                 goto out_unlock;
     60                return;
    6761
    6862        item.ct = ct;
     
    7064        item.report = 0;
    7165
    72         ret = min( notify ? notify->fcn(events | missed, &item) : 0,
    73                            notify_2 ? notify_2->fcn(events | missed, &item) : 0);
    74 
    75         if (likely(ret >= 0 && !missed))
    76                 goto out_unlock;
     66        atomic_notifier_call_chain(&net->ct.nf_conntrack_chain,
     67                        events | missed,
     68                        &item);
     69
     70        if (likely(!missed))
     71                return;
    7772
    7873        spin_lock_bh(&ct->lock);
    79         if (ret < 0)
    80                 e->missed |= events;
    81         else
    82                 e->missed &= ~missed;
     74        e->missed &= ~missed;
    8375        spin_unlock_bh(&ct->lock);
    84 
    85 out_unlock:
    86         rcu_read_unlock();
    8776}
    8877EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events);
    8978
    90 int nf_conntrack_register_notifier(struct net *net,
    91                                    struct nf_ct_event_notifier *new)
    92 {
    93         int ret;
    94         struct nf_ct_event_notifier *notify;
    95         struct nf_ct_event_notifier *notify_2;
    96 
    97         mutex_lock(&nf_ct_ecache_mutex);
    98         notify = rcu_dereference_protected(net->ct.nf_conntrack_event_cb,
    99                                            lockdep_is_held(&nf_ct_ecache_mutex));
    100         notify_2 = rcu_dereference_protected(net->ct.nf_conntrack_event_cb_2,
    101                                            lockdep_is_held(&nf_ct_ecache_mutex));
    102         if ( (notify != NULL) && (notify_2 != NULL) ) {
    103                 ret = -EBUSY;
    104                 goto out_unlock;
    105         }
    106         if (notify == NULL)
    107             rcu_assign_pointer(net->ct.nf_conntrack_event_cb, new);
    108         else
    109             rcu_assign_pointer(net->ct.nf_conntrack_event_cb_2, new);
    110         ret = 0;
    111 
    112 out_unlock:
    113         mutex_unlock(&nf_ct_ecache_mutex);
    114         return ret;
     79int nf_conntrack_register_notifier(struct net *net, struct notifier_block *nb)
     80{
     81        return atomic_notifier_chain_register(&net->ct.nf_conntrack_chain, nb);
    11582}
    11683EXPORT_SYMBOL_GPL(nf_conntrack_register_notifier);
    11784
    118 void nf_conntrack_unregister_notifier(struct net *net,
    119                                       struct nf_ct_event_notifier *new)
    120 {
    121         struct nf_ct_event_notifier *notify;
    122         struct nf_ct_event_notifier *notify_2;
    123 
    124         mutex_lock(&nf_ct_ecache_mutex);
    125         notify = rcu_dereference_protected(net->ct.nf_conntrack_event_cb,
    126                                            lockdep_is_held(&nf_ct_ecache_mutex));
    127         notify_2 = rcu_dereference_protected(net->ct.nf_conntrack_event_cb_2,
    128                                            lockdep_is_held(&nf_ct_ecache_mutex));
    129         BUG_ON((notify != new) || (notify_2 != new));
    130         if (notify == new)
    131             RCU_INIT_POINTER(net->ct.nf_conntrack_event_cb, NULL);
    132         else
    133             RCU_INIT_POINTER(net->ct.nf_conntrack_event_cb_2, NULL);
    134         mutex_unlock(&nf_ct_ecache_mutex);
     85int nf_conntrack_unregister_notifier(struct net *net, struct notifier_block *nb)
     86{
     87        return atomic_notifier_chain_unregister(&net->ct.nf_conntrack_chain, nb);
    13588}
    13689EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier);
  • src/linux/universal/linux-3.10/net/netfilter/nf_conntrack_netlink.c

    r21952 r32623  
    2929#include <linux/spinlock.h>
    3030#include <linux/interrupt.h>
     31#include <linux/notifier.h>
    3132#include <linux/slab.h>
    3233
     
    603604
    604605#ifdef CONFIG_NF_CONNTRACK_EVENTS
    605 static int
    606 ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item)
     606static int ctnetlink_conntrack_event(struct notifier_block *this,
     607                                     unsigned long events, void *ptr)
    607608{
    608609        struct net *net;
     
    610611        struct nfgenmsg *nfmsg;
    611612        struct nlattr *nest_parms;
     613        struct nf_ct_event *item = ptr;
    612614        struct nf_conn *ct = item->ct;
    613615        struct sk_buff *skb;
     
    29802982
    29812983#ifdef CONFIG_NF_CONNTRACK_EVENTS
    2982 static struct nf_ct_event_notifier ctnl_notifier = {
    2983         .fcn = ctnetlink_conntrack_event,
     2984static struct notifier_block ctnl_notifier = {
     2985        .notifier_call = ctnetlink_conntrack_event,
    29842986};
    29852987
  • src/linux/universal/linux-3.18/include/linux/if_bridge.h

    r25370 r32623  
    3434
    3535extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *));
     36extern void br_dev_update_stats(struct net_device *dev, struct rtnl_link_stats64 *nlstats);
    3637
    3738typedef int br_should_route_hook_t(struct sk_buff *skb);
  • src/linux/universal/linux-3.18/include/linux/skbuff.h

    r32622 r32623  
    609609        __u8                    ipvs_property:1;
    610610        __u8                    inner_protocol_type:1;
     611        __u8                    fast_forwarded:1;
    611612        __u8                    gro_skip:1;
    612613        /* 3 or 5 bit hole */
  • src/linux/universal/linux-3.18/include/net/netfilter/nf_conntrack_ecache.h

    r25370 r32623  
    6464};
    6565
    66 struct nf_ct_event_notifier {
    67         int (*fcn)(unsigned int events, struct nf_ct_event *item);
    68 };
    69 
    70 int nf_conntrack_register_notifier(struct net *net,
    71                                    struct nf_ct_event_notifier *nb);
    72 void nf_conntrack_unregister_notifier(struct net *net,
    73                                       struct nf_ct_event_notifier *nb);
     66extern int nf_conntrack_register_notifier(struct net *net, struct notifier_block *nb);
     67extern int nf_conntrack_unregister_notifier(struct net *net, struct notifier_block *nb);
    7468
    7569void nf_ct_deliver_cached_events(struct nf_conn *ct);
     
    7872nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct)
    7973{
    80         struct net *net = nf_ct_net(ct);
    81         struct nf_conntrack_ecache *e;
    82 
    83         if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb) && !rcu_access_pointer(net->ct.nf_conntrack_event_cb_2))
    84                 return;
     74        struct nf_conntrack_ecache *e;
    8575
    8676        e = nf_ct_ecache_find(ct);
     
    9787                              int report)
    9888{
    99         int ret = 0;
     89        struct nf_conntrack_ecache *e;
     90
    10091        struct net *net = nf_ct_net(ct);
    101         struct nf_ct_event_notifier *notify;
    102         struct nf_ct_event_notifier *notify_2;
    103         struct nf_conntrack_ecache *e;
    104 
    105         rcu_read_lock();
    106         /* Incredibly nasty duplication in order to hack second event */
    107         notify = rcu_dereference(net->ct.nf_conntrack_event_cb);
    108         notify_2 = rcu_dereference(net->ct.nf_conntrack_event_cb_2);
    109         if ((notify == NULL) && (notify_2 == NULL))
    110                 goto out_unlock;
    11192
    11293        e = nf_ct_ecache_find(ct);
    11394        if (e == NULL)
    114                 goto out_unlock;
     95                return 0;
    11596
    11697        if (nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct)) {
     
    124105
    125106                if (!((eventmask | missed) & e->ctmask))
    126                         goto out_unlock;
    127 
    128                 ret = min( notify ? notify->fcn(eventmask | missed, &item) : 0,
    129                            notify_2 ? notify_2->fcn(eventmask | missed, &item) : 0 );
    130                 if (unlikely(ret < 0 || missed)) {
    131                         spin_lock_bh(&ct->lock);
    132                         if (ret < 0) {
    133                                 /* This is a destroy event that has been
    134                                  * triggered by a process, we store the PORTID
    135                                  * to include it in the retransmission. */
    136                                 if (eventmask & (1 << IPCT_DESTROY) &&
    137                                     e->portid == 0 && portid != 0)
    138                                         e->portid = portid;
    139                                 else
    140                                         e->missed |= eventmask;
    141                         } else
    142                                 e->missed &= ~missed;
    143                         spin_unlock_bh(&ct->lock);
    144                 }
    145         }
    146 out_unlock:
    147         rcu_read_unlock();
    148         return ret;
     107                        return 0;
     108
     109                atomic_notifier_call_chain(&net->ct.nf_conntrack_chain, eventmask | missed, &item);
     110        }
     111
     112        return 0;
    149113}
    150114
  • src/linux/universal/linux-3.18/include/net/netns/conntrack.h

    r25370 r32623  
    102102        struct ct_pcpu __percpu *pcpu_lists;
    103103        struct ip_conntrack_stat __percpu *stat;
    104         struct nf_ct_event_notifier __rcu *nf_conntrack_event_cb;
    105         struct nf_ct_event_notifier __rcu *nf_conntrack_event_cb_2;
     104        struct atomic_notifier_head nf_conntrack_chain;
    106105        struct nf_exp_event_notifier __rcu *nf_expect_event_cb;
    107106        struct nf_ip_net        nf_ct_proto;
  • src/linux/universal/linux-3.18/net/bridge/br_if.c

    r25370 r32623  
    578578                nbp_update_port_count(br);
    579579}
     580
     581/* Update bridge statistics for bridge packets processed by offload engines */
     582void br_dev_update_stats(struct net_device *dev, struct rtnl_link_stats64 *nlstats)
     583{
     584        struct net_bridge *br;
     585        struct pcpu_sw_netstats *stats;
     586
     587        /*
     588         * Is this a bridge?
     589         */
     590        if (!(dev->priv_flags & IFF_EBRIDGE))
     591                return;
     592
     593        br = netdev_priv(dev);
     594        stats = per_cpu_ptr(br->stats, 0);
     595
     596        u64_stats_update_begin(&stats->syncp);
     597        stats->rx_packets += nlstats->rx_packets;
     598        stats->rx_bytes += nlstats->rx_bytes;
     599        stats->tx_packets += nlstats->tx_packets;
     600        stats->tx_bytes += nlstats->tx_bytes;
     601        u64_stats_update_end(&stats->syncp);
     602}
     603EXPORT_SYMBOL_GPL(br_dev_update_stats);
  • src/linux/universal/linux-3.18/net/core/dev.c

    r32622 r32623  
    26242624        int rc;
    26252625
     2626        /*
     2627         * If this skb has been fast forwarded then we don't want it to
     2628         * go to any taps (by definition we're trying to bypass them).
     2629         */
     2630        if (!skb->fast_forwarded) {
    26262631#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
    2627         if ( !list_empty(&ptype_all) &&
     2632        if (!list_empty(&ptype_all) &&
    26282633                !(skb->imq_flags & IMQ_F_ENQUEUE))
    26292634#else
    2630                 if (!list_empty(&ptype_all)) 
     2635                if (!list_empty(&ptype_all))
    26312636#endif
    26322637                dev_queue_xmit_nit(skb, dev);
     2638        }
    26332639
    26342640#ifdef CONFIG_ETHERNET_PACKET_MANGLE
     
    36183624EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister);
    36193625
     3626int (*fast_nat_recv)(struct sk_buff *skb) __rcu __read_mostly;
     3627EXPORT_SYMBOL_GPL(fast_nat_recv);
     3628
    36203629/*
    36213630 * Limit the use of PFMEMALLOC reserves to those protocols that implement
     
    36453654        int ret = NET_RX_DROP;
    36463655        __be16 type;
     3656        int (*fast_recv)(struct sk_buff *skb);
    36473657
    36483658        net_timestamp_check(!netdev_tstamp_prequeue, skb);
     
    36703680                if (unlikely(!skb))
    36713681                        goto out;
     3682        }
     3683
     3684        fast_recv = rcu_dereference(fast_nat_recv);
     3685        if (fast_recv && fast_recv(skb)) {
     3686                ret = NET_RX_SUCCESS;
     3687                goto out;
    36723688        }
    36733689
  • src/linux/universal/linux-3.18/net/netfilter/nf_conntrack_core.c

    r29844 r32623  
    18161816        if (ret < 0)
    18171817                goto err_proto;
     1818        ATOMIC_INIT_NOTIFIER_HEAD(&net->ct.nf_conntrack_chain);
    18181819        return 0;
    18191820
  • src/linux/universal/linux-3.18/net/netfilter/nf_conntrack_ecache.c

    r25370 r32623  
    1919#include <linux/err.h>
    2020#include <linux/percpu.h>
     21#include <linux/notifier.h>
    2122#include <linux/kernel.h>
    2223#include <linux/netdevice.h>
     
    118119void nf_ct_deliver_cached_events(struct nf_conn *ct)
    119120{
    120         struct net *net = nf_ct_net(ct);
    121121        unsigned long events, missed;
    122122        /* Incredibly nasty duplication in order to hack second event */
    123         struct nf_ct_event_notifier *notify;
    124         struct nf_ct_event_notifier *notify_2;
    125123        struct nf_conntrack_ecache *e;
    126124        struct nf_ct_event item;
    127125        int ret;
    128126
    129         rcu_read_lock();
    130         notify = rcu_dereference(net->ct.nf_conntrack_event_cb);
    131         notify_2 = rcu_dereference(net->ct.nf_conntrack_event_cb_2);
    132         if ( (notify == NULL) && (notify_2 == NULL) )
    133                 goto out_unlock;
     127        struct net *net = nf_ct_net(ct);
    134128
    135129        e = nf_ct_ecache_find(ct);
    136130        if (e == NULL)
    137                 goto out_unlock;
     131                return;
    138132
    139133        events = xchg(&e->cache, 0);
    140134
    141135        if (!nf_ct_is_confirmed(ct) || nf_ct_is_dying(ct) || !events)
    142                 goto out_unlock;
     136                return;
    143137
    144138        /* We make a copy of the missed event cache without taking
     
    148142
    149143        if (!((events | missed) & e->ctmask))
    150                 goto out_unlock;
     144                return;
    151145
    152146        item.ct = ct;
     
    154148        item.report = 0;
    155149
    156         ret = min( notify ? notify->fcn(events | missed, &item) : 0,
    157                            notify_2 ? notify_2->fcn(events | missed, &item) : 0);
    158 
    159         if (likely(ret >= 0 && !missed))
    160                 goto out_unlock;
     150        atomic_notifier_call_chain(&net->ct.nf_conntrack_chain,
     151                        events | missed,
     152                        &item);
     153
     154        if (likely(!missed))
     155                return;
    161156
    162157        spin_lock_bh(&ct->lock);
    163         if (ret < 0)
    164                 e->missed |= events;
    165         else
    166                 e->missed &= ~missed;
     158        e->missed &= ~missed;
    167159        spin_unlock_bh(&ct->lock);
    168 
    169 out_unlock:
    170         rcu_read_unlock();
    171160}
    172161EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events);
    173162
    174 int nf_conntrack_register_notifier(struct net *net,
    175                                    struct nf_ct_event_notifier *new)
    176 {
    177         int ret;
    178         struct nf_ct_event_notifier *notify;
    179         struct nf_ct_event_notifier *notify_2;
    180 
    181         mutex_lock(&nf_ct_ecache_mutex);
    182         notify = rcu_dereference_protected(net->ct.nf_conntrack_event_cb,
    183                                            lockdep_is_held(&nf_ct_ecache_mutex));
    184         notify_2 = rcu_dereference_protected(net->ct.nf_conntrack_event_cb_2,
    185                                            lockdep_is_held(&nf_ct_ecache_mutex));
    186         if ( (notify != NULL) && (notify_2 != NULL) ) {
    187                 ret = -EBUSY;
    188                 goto out_unlock;
    189         }
    190         if (notify == NULL)
    191             rcu_assign_pointer(net->ct.nf_conntrack_event_cb, new);
    192         else
    193             rcu_assign_pointer(net->ct.nf_conntrack_event_cb_2, new);
    194         ret = 0;
    195 
    196 out_unlock:
    197         mutex_unlock(&nf_ct_ecache_mutex);
    198         return ret;
     163int nf_conntrack_register_notifier(struct net *net, struct notifier_block *nb)
     164{
     165        return atomic_notifier_chain_register(&net->ct.nf_conntrack_chain, nb);
    199166}
    200167EXPORT_SYMBOL_GPL(nf_conntrack_register_notifier);
    201168
    202 void nf_conntrack_unregister_notifier(struct net *net,
    203                                       struct nf_ct_event_notifier *new)
    204 {
    205         struct nf_ct_event_notifier *notify;
    206         struct nf_ct_event_notifier *notify_2;
    207 
    208         mutex_lock(&nf_ct_ecache_mutex);
    209         notify = rcu_dereference_protected(net->ct.nf_conntrack_event_cb,
    210                                            lockdep_is_held(&nf_ct_ecache_mutex));
    211         notify_2 = rcu_dereference_protected(net->ct.nf_conntrack_event_cb_2,
    212                                            lockdep_is_held(&nf_ct_ecache_mutex));
    213         BUG_ON((notify != new) || (notify_2 != new));
    214         if (notify == new)
    215             RCU_INIT_POINTER(net->ct.nf_conntrack_event_cb, NULL);
    216         else
    217             RCU_INIT_POINTER(net->ct.nf_conntrack_event_cb_2, NULL);
    218         mutex_unlock(&nf_ct_ecache_mutex);
     169int nf_conntrack_unregister_notifier(struct net *net, struct notifier_block *nb)
     170{
     171        return atomic_notifier_chain_unregister(&net->ct.nf_conntrack_chain, nb);
    219172}
    220173EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier);
  • src/linux/universal/linux-3.18/net/netfilter/nf_conntrack_netlink.c

    r32569 r32623  
    2929#include <linux/spinlock.h>
    3030#include <linux/interrupt.h>
     31#include <linux/notifier.h>
    3132#include <linux/slab.h>
    3233
     
    609610
    610611#ifdef CONFIG_NF_CONNTRACK_EVENTS
    611 static int
    612 ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item)
     612static int ctnetlink_conntrack_event(struct notifier_block *this,
     613                                     unsigned long events, void *ptr)
    613614{
    614615        struct net *net;
     
    616617        struct nfgenmsg *nfmsg;
    617618        struct nlattr *nest_parms;
     619        struct nf_ct_event *item = ptr;
    618620        struct nf_conn *ct = item->ct;
    619621        struct sk_buff *skb;
     
    30903092
    30913093#ifdef CONFIG_NF_CONNTRACK_EVENTS
    3092 static struct nf_ct_event_notifier ctnl_notifier = {
    3093         .fcn = ctnetlink_conntrack_event,
     3094static struct notifier_block ctnl_notifier = {
     3095        .notifier_call = ctnetlink_conntrack_event,
    30943096};
    30953097
  • src/linux/universal/linux-4.4/include/linux/if_bridge.h

    r29492 r32623  
    5252
    5353extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *));
     54extern void br_dev_update_stats(struct net_device *dev, struct rtnl_link_stats64 *nlstats);
    5455
    5556typedef int br_should_route_hook_t(struct sk_buff *skb);
  • src/linux/universal/linux-4.4/include/linux/skbuff.h

    r32622 r32623  
    652652        __u8                    ipvs_property:1;
    653653        __u8                    inner_protocol_type:1;
     654        __u8                    fast_forwarded:1;
    654655        __u8                    remcsum_offload:1;
    655656        __u8                    gro_skip:1;
    656         /* 2 or 4 bit hole */
     657        /* 1 or 2 bit hole */
    657658
    658659#ifdef CONFIG_NET_SCHED
  • src/linux/universal/linux-4.4/include/net/netfilter/nf_conntrack_ecache.h

    r28606 r32623  
    6464};
    6565
    66 struct nf_ct_event_notifier {
    67         int (*fcn)(unsigned int events, struct nf_ct_event *item);
    68 };
    69 
    70 int nf_conntrack_register_notifier(struct net *net,
    71                                    struct nf_ct_event_notifier *nb);
    72 void nf_conntrack_unregister_notifier(struct net *net,
    73                                       struct nf_ct_event_notifier *nb);
     66extern int nf_conntrack_register_notifier(struct net *net, struct notifier_block *nb);
     67extern int nf_conntrack_unregister_notifier(struct net *net, struct notifier_block *nb);
    7468
    7569void nf_ct_deliver_cached_events(struct nf_conn *ct);
     
    7872nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct)
    7973{
    80         struct net *net = nf_ct_net(ct);
    81         struct nf_conntrack_ecache *e;
    82 
    83         if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb) && !rcu_access_pointer(net->ct.nf_conntrack_event_cb_2))
    84                 return;
     74        struct nf_conntrack_ecache *e;
    8575
    8676        e = nf_ct_ecache_find(ct);
     
    9787                              int report)
    9888{
    99         int ret = 0;
     89        struct nf_conntrack_ecache *e;
     90
    10091        struct net *net = nf_ct_net(ct);
    101         struct nf_ct_event_notifier *notify;
    102         struct nf_ct_event_notifier *notify_2;
    103         struct nf_conntrack_ecache *e;
    104 
    105         rcu_read_lock();
    106         /* Incredibly nasty duplication in order to hack second event */
    107         notify = rcu_dereference(net->ct.nf_conntrack_event_cb);
    108         notify_2 = rcu_dereference(net->ct.nf_conntrack_event_cb_2);
    109         if ((notify == NULL) && (notify_2 == NULL))
    110                 goto out_unlock;
    11192
    11293        e = nf_ct_ecache_find(ct);
    11394        if (e == NULL)
    114                 goto out_unlock;
     95                return 0;
    11596
    11697        if (nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct)) {
     
    124105
    125106                if (!((eventmask | missed) & e->ctmask))
    126                         goto out_unlock;
    127 
    128                 ret = min( notify ? notify->fcn(eventmask | missed, &item) : 0,
    129                            notify_2 ? notify_2->fcn(eventmask | missed, &item) : 0 );
    130                 if (unlikely(ret < 0 || missed)) {
    131                         spin_lock_bh(&ct->lock);
    132                         if (ret < 0) {
    133                                 /* This is a destroy event that has been
    134                                  * triggered by a process, we store the PORTID
    135                                  * to include it in the retransmission. */
    136                                 if (eventmask & (1 << IPCT_DESTROY) &&
    137                                     e->portid == 0 && portid != 0)
    138                                         e->portid = portid;
    139                                 else
    140                                         e->missed |= eventmask;
    141                         } else
    142                                 e->missed &= ~missed;
    143                         spin_unlock_bh(&ct->lock);
    144                 }
    145         }
    146 out_unlock:
    147         rcu_read_unlock();
    148         return ret;
     107                        return 0;
     108
     109                atomic_notifier_call_chain(&net->ct.nf_conntrack_chain, eventmask | missed, &item);
     110        }
     111
     112        return 0;
    149113}
    150114
  • src/linux/universal/linux-4.4/include/net/netns/conntrack.h

    r28606 r32623  
    101101        struct ct_pcpu __percpu *pcpu_lists;
    102102        struct ip_conntrack_stat __percpu *stat;
    103         struct nf_ct_event_notifier __rcu *nf_conntrack_event_cb;
    104         struct nf_ct_event_notifier __rcu *nf_conntrack_event_cb_2;
     103        struct atomic_notifier_head nf_conntrack_chain;
    105104        struct nf_exp_event_notifier __rcu *nf_expect_event_cb;
    106105        struct nf_ip_net        nf_ct_proto;
  • src/linux/universal/linux-4.4/net/bridge/br_if.c

    r28781 r32623  
    589589                nbp_update_port_count(br);
    590590}
     591
     592/* Update bridge statistics for bridge packets processed by offload engines */
     593void br_dev_update_stats(struct net_device *dev, struct rtnl_link_stats64 *nlstats)
     594{
     595        struct net_bridge *br;
     596        struct pcpu_sw_netstats *stats;
     597
     598        /*
     599         * Is this a bridge?
     600         */
     601        if (!(dev->priv_flags & IFF_EBRIDGE))
     602                return;
     603
     604        br = netdev_priv(dev);
     605        stats = per_cpu_ptr(br->stats, 0);
     606
     607        u64_stats_update_begin(&stats->syncp);
     608        stats->rx_packets += nlstats->rx_packets;
     609        stats->rx_bytes += nlstats->rx_bytes;
     610        stats->tx_packets += nlstats->tx_packets;
     611        stats->tx_bytes += nlstats->tx_bytes;
     612        u64_stats_update_end(&stats->syncp);
     613}
     614EXPORT_SYMBOL_GPL(br_dev_update_stats);
  • src/linux/universal/linux-4.4/net/core/dev.c

    r32622 r32623  
    27412741        int rc;
    27422742
     2743        /*
     2744         * If this skb has been fast forwarded then we don't want it to
     2745         * go to any taps (by definition we're trying to bypass them).
     2746         */
     2747        if (!skb->fast_forwarded) {
    27432748#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
    2744         if ((!list_empty(&ptype_all) || !list_empty(&dev->ptype_all)) &&
     2749        if (!list_empty(&ptype_all) &&
    27452750                !(skb->imq_flags & IMQ_F_ENQUEUE))
    27462751#else
    2747         if (!list_empty(&ptype_all) || !list_empty(&dev->ptype_all))
     2752                if (!list_empty(&ptype_all))
    27482753#endif
    27492754                dev_queue_xmit_nit(skb, dev);
    2750 
     2755        }
    27512756
    27522757#ifdef CONFIG_ETHERNET_PACKET_MANGLE
     
    38393844EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister);
    38403845
     3846int (*fast_nat_recv)(struct sk_buff *skb) __rcu __read_mostly;
     3847EXPORT_SYMBOL_GPL(fast_nat_recv);
     3848
    38413849/*
    38423850 * Limit the use of PFMEMALLOC reserves to those protocols that implement
     
    38813889        int ret = NET_RX_DROP;
    38823890        __be16 type;
     3891        int (*fast_recv)(struct sk_buff *skb);
    38833892
    38843893        net_timestamp_check(!netdev_tstamp_prequeue, skb);
     
    39063915                if (unlikely(!skb))
    39073916                        goto out;
     3917        }
     3918
     3919        fast_recv = rcu_dereference(fast_nat_recv);
     3920        if (fast_recv && fast_recv(skb)) {
     3921                ret = NET_RX_SUCCESS;
     3922                goto out;
    39083923        }
    39093924
  • src/linux/universal/linux-4.4/net/netfilter/nf_conntrack_core.c

    r29744 r32623  
    18331833        if (ret < 0)
    18341834                goto err_proto;
     1835        ATOMIC_INIT_NOTIFIER_HEAD(&net->ct.nf_conntrack_chain);
    18351836        return 0;
    18361837
  • src/linux/universal/linux-4.4/net/netfilter/nf_conntrack_ecache.c

    r28606 r32623  
    1919#include <linux/err.h>
    2020#include <linux/percpu.h>
     21#include <linux/notifier.h>
    2122#include <linux/kernel.h>
    2223#include <linux/netdevice.h>
     
    118119void nf_ct_deliver_cached_events(struct nf_conn *ct)
    119120{
    120         struct net *net = nf_ct_net(ct);
    121121        unsigned long events, missed;
    122122        /* Incredibly nasty duplication in order to hack second event */
    123         struct nf_ct_event_notifier *notify;
    124         struct nf_ct_event_notifier *notify_2;
    125123        struct nf_conntrack_ecache *e;
    126124        struct nf_ct_event item;
    127125        int ret;
    128126
    129         rcu_read_lock();
    130         notify = rcu_dereference(net->ct.nf_conntrack_event_cb);
    131         notify_2 = rcu_dereference(net->ct.nf_conntrack_event_cb_2);
    132         if ( (notify == NULL) && (notify_2 == NULL) )
    133                 goto out_unlock;
     127        struct net *net = nf_ct_net(ct);
    134128
    135129        e = nf_ct_ecache_find(ct);
    136130        if (e == NULL)
    137                 goto out_unlock;
     131                return;
    138132
    139133        events = xchg(&e->cache, 0);
    140134
    141135        if (!nf_ct_is_confirmed(ct) || nf_ct_is_dying(ct) || !events)
    142                 goto out_unlock;
     136                return;
    143137
    144138        /* We make a copy of the missed event cache without taking
     
    148142
    149143        if (!((events | missed) & e->ctmask))
    150                 goto out_unlock;
     144                return;
    151145
    152146        item.ct = ct;
     
    154148        item.report = 0;
    155149
    156         ret = min( notify ? notify->fcn(events | missed, &item) : 0,
    157                            notify_2 ? notify_2->fcn(events | missed, &item) : 0);
    158 
    159         if (likely(ret >= 0 && !missed))
    160                 goto out_unlock;
     150        atomic_notifier_call_chain(&net->ct.nf_conntrack_chain,
     151                        events | missed,
     152                        &item);
     153
     154        if (likely(!missed))
     155                return;
    161156
    162157        spin_lock_bh(&ct->lock);
    163         if (ret < 0)
    164                 e->missed |= events;
    165         else
    166                 e->missed &= ~missed;
     158        e->missed &= ~missed;
    167159        spin_unlock_bh(&ct->lock);
    168 
    169 out_unlock:
    170         rcu_read_unlock();
    171160}
    172161EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events);
    173162
    174 int nf_conntrack_register_notifier(struct net *net,
    175                                    struct nf_ct_event_notifier *new)
    176 {
    177         int ret;
    178         struct nf_ct_event_notifier *notify;
    179         struct nf_ct_event_notifier *notify_2;
    180 
    181         mutex_lock(&nf_ct_ecache_mutex);
    182         notify = rcu_dereference_protected(net->ct.nf_conntrack_event_cb,
    183                                            lockdep_is_held(&nf_ct_ecache_mutex));
    184         notify_2 = rcu_dereference_protected(net->ct.nf_conntrack_event_cb_2,
    185                                            lockdep_is_held(&nf_ct_ecache_mutex));
    186         if ( (notify != NULL) && (notify_2 != NULL) ) {
    187                 ret = -EBUSY;
    188                 goto out_unlock;
    189         }
    190         if (notify == NULL)
    191             rcu_assign_pointer(net->ct.nf_conntrack_event_cb, new);
    192         else
    193             rcu_assign_pointer(net->ct.nf_conntrack_event_cb_2, new);
    194         ret = 0;
    195 
    196 out_unlock:
    197         mutex_unlock(&nf_ct_ecache_mutex);
    198         return ret;
     163int nf_conntrack_register_notifier(struct net *net, struct notifier_block *nb)
     164{
     165        return atomic_notifier_chain_register(&net->ct.nf_conntrack_chain, nb);
    199166}
    200167EXPORT_SYMBOL_GPL(nf_conntrack_register_notifier);
    201168
    202 void nf_conntrack_unregister_notifier(struct net *net,
    203                                       struct nf_ct_event_notifier *new)
    204 {
    205         struct nf_ct_event_notifier *notify;
    206         struct nf_ct_event_notifier *notify_2;
    207 
    208         mutex_lock(&nf_ct_ecache_mutex);
    209         notify = rcu_dereference_protected(net->ct.nf_conntrack_event_cb,
    210                                            lockdep_is_held(&nf_ct_ecache_mutex));
    211         notify_2 = rcu_dereference_protected(net->ct.nf_conntrack_event_cb_2,
    212                                            lockdep_is_held(&nf_ct_ecache_mutex));
    213         BUG_ON((notify != new) || (notify_2 != new));
    214         if (notify == new)
    215             RCU_INIT_POINTER(net->ct.nf_conntrack_event_cb, NULL);
    216         else
    217             RCU_INIT_POINTER(net->ct.nf_conntrack_event_cb_2, NULL);
    218         mutex_unlock(&nf_ct_ecache_mutex);
     169int nf_conntrack_unregister_notifier(struct net *net, struct notifier_block *nb)
     170{
     171        return atomic_notifier_chain_unregister(&net->ct.nf_conntrack_chain, nb);
    219172}
    220173EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier);
  • src/linux/universal/linux-4.4/net/netfilter/nf_conntrack_netlink.c

    r32569 r32623  
    2929#include <linux/spinlock.h>
    3030#include <linux/interrupt.h>
     31#include <linux/notifier.h>
    3132#include <linux/slab.h>
    3233
     
    632633
    633634#ifdef CONFIG_NF_CONNTRACK_EVENTS
    634 static int
    635 ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item)
     635static int ctnetlink_conntrack_event(struct notifier_block *this,
     636                                     unsigned long events, void *ptr)
    636637{
    637638        const struct nf_conntrack_zone *zone;
     
    640641        struct nfgenmsg *nfmsg;
    641642        struct nlattr *nest_parms;
     643        struct nf_ct_event *item = ptr;
    642644        struct nf_conn *ct = item->ct;
    643645        struct sk_buff *skb;
     
    32633265
    32643266#ifdef CONFIG_NF_CONNTRACK_EVENTS
    3265 static struct nf_ct_event_notifier ctnl_notifier = {
    3266         .fcn = ctnetlink_conntrack_event,
     3267static struct notifier_block ctnl_notifier = {
     3268        .notifier_call = ctnetlink_conntrack_event,
    32673269};
    32683270
  • src/linux/universal/linux-4.9/include/linux/if_bridge.h

    r31576 r32623  
    5454
    5555extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *));
     56extern void br_dev_update_stats(struct net_device *dev, struct rtnl_link_stats64 *nlstats);
    5657
    5758typedef int br_should_route_hook_t(struct sk_buff *skb);
  • src/linux/universal/linux-4.9/include/linux/skbuff.h

    r32622 r32623  
    750750        __u8                    ipvs_property:1;
    751751        __u8                    inner_protocol_type:1;
     752        __u8                    fast_forwarded:1;
    752753        __u8                    remcsum_offload:1;
    753754#ifdef CONFIG_NET_SWITCHDEV
  • src/linux/universal/linux-4.9/include/net/netfilter/nf_conntrack_ecache.h

    r31574 r32623  
    7171};
    7272
    73 struct nf_ct_event_notifier {
    74         int (*fcn)(unsigned int events, struct nf_ct_event *item);
    75 };
    76 
    77 int nf_conntrack_register_notifier(struct net *net,
    78                                    struct nf_ct_event_notifier *nb);
    79 void nf_conntrack_unregister_notifier(struct net *net,
    80                                       struct nf_ct_event_notifier *nb);
     73extern int nf_conntrack_register_notifier(struct net *net, struct notifier_block *nb);
     74extern int nf_conntrack_unregister_notifier(struct net *net, struct notifier_block *nb);
    8175
    8276void nf_ct_deliver_cached_events(struct nf_conn *ct);
     
    8781nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct)
    8882{
    89         struct net *net = nf_ct_net(ct);
    9083        struct nf_conntrack_ecache *e;
    91 
    92         if (!rcu_access_pointer(net->ct.nf_conntrack_event_cb) && !rcu_access_pointer(net->ct.nf_conntrack_event_cb_2))
    93                 return;
    9484
    9585        e = nf_ct_ecache_find(ct);
  • src/linux/universal/linux-4.9/include/net/netns/conntrack.h

    r31574 r32623  
    8787        struct ct_pcpu __percpu *pcpu_lists;
    8888        struct ip_conntrack_stat __percpu *stat;
    89         struct nf_ct_event_notifier __rcu *nf_conntrack_event_cb;
    90         struct nf_ct_event_notifier __rcu *nf_conntrack_event_cb_2;
     89        struct atomic_notifier_head nf_conntrack_chain;
    9190        struct nf_exp_event_notifier __rcu *nf_expect_event_cb;
    9291        struct nf_ip_net        nf_ct_proto;
  • src/linux/universal/linux-4.9/net/bridge/br_if.c

    r31574 r32623  
    656656                nbp_update_port_count(br);
    657657}
     658
     659/* Update bridge statistics for bridge packets processed by offload engines */
     660void br_dev_update_stats(struct net_device *dev, struct rtnl_link_stats64 *nlstats)
     661{
     662        struct net_bridge *br;
     663        struct pcpu_sw_netstats *stats;
     664
     665        /*
     666         * Is this a bridge?
     667         */
     668        if (!(dev->priv_flags & IFF_EBRIDGE))
     669                return;
     670
     671        br = netdev_priv(dev);
     672        stats = per_cpu_ptr(br->stats, 0);
     673
     674        u64_stats_update_begin(&stats->syncp);
     675        stats->rx_packets += nlstats->rx_packets;
     676        stats->rx_bytes += nlstats->rx_bytes;
     677        stats->tx_packets += nlstats->tx_packets;
     678        stats->tx_bytes += nlstats->tx_bytes;
     679        u64_stats_update_end(&stats->syncp);
     680}
     681EXPORT_SYMBOL_GPL(br_dev_update_stats);
  • src/linux/universal/linux-4.9/net/core/dev.c

    r32622 r32623  
    29372937        int rc;
    29382938
     2939        /*
     2940         * If this skb has been fast forwarded then we don't want it to
     2941         * go to any taps (by definition we're trying to bypass them).
     2942         */
     2943        if (!skb->fast_forwarded) {
    29392944#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
    2940         if ((!list_empty(&ptype_all) || !list_empty(&dev->ptype_all)) &&
     2945        if (!list_empty(&ptype_all) &&
    29412946                !(skb->imq_flags & IMQ_F_ENQUEUE))
    29422947#else
    2943         if (!list_empty(&ptype_all) || !list_empty(&dev->ptype_all))
     2948                if (!list_empty(&ptype_all))
    29442949#endif
    29452950                dev_queue_xmit_nit(skb, dev);
    2946 
     2951        }
    29472952
    29482953#ifdef CONFIG_ETHERNET_PACKET_MANGLE
     
    40754080EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister);
    40764081
     4082int (*fast_nat_recv)(struct sk_buff *skb) __rcu __read_mostly;
     4083EXPORT_SYMBOL_GPL(fast_nat_recv);
     4084
    40774085/*
    40784086 * Limit the use of PFMEMALLOC reserves to those protocols that implement
     
    41224130        int ret = NET_RX_DROP;
    41234131        __be16 type;
     4132        int (*fast_recv)(struct sk_buff *skb);
    41244133
    41254134        net_timestamp_check(!netdev_tstamp_prequeue, skb);
     
    41474156                if (unlikely(!skb))
    41484157                        goto out;
     4158        }
     4159
     4160        fast_recv = rcu_dereference(fast_nat_recv);
     4161        if (fast_recv && fast_recv(skb)) {
     4162                ret = NET_RX_SUCCESS;
     4163                goto out;
    41494164        }
    41504165
  • src/linux/universal/linux-4.9/net/netfilter/nf_conntrack_core.c

    r31632 r32623  
    20142014        if (ret < 0)
    20152015                goto err_proto;
     2016        ATOMIC_INIT_NOTIFIER_HEAD(&net->ct.nf_conntrack_chain);
    20162017        return 0;
    20172018
  • src/linux/universal/linux-4.9/net/netfilter/nf_conntrack_ecache.c

    r31574 r32623  
    1919#include <linux/err.h>
    2020#include <linux/percpu.h>
     21#include <linux/notifier.h>
    2122#include <linux/kernel.h>
    2223#include <linux/netdevice.h>
     
    121122                                  u32 portid, int report)
    122123{
    123         int ret = 0;
     124        struct nf_conntrack_ecache *e;
     125
    124126        struct net *net = nf_ct_net(ct);
    125         struct nf_ct_event_notifier *notify;
    126         struct nf_ct_event_notifier *notify_2;
    127         struct nf_conntrack_ecache *e;
    128 
    129         rcu_read_lock();
    130         notify = rcu_dereference(net->ct.nf_conntrack_event_cb);
    131         notify_2 = rcu_dereference(net->ct.nf_conntrack_event_cb_2);
    132         if ((notify == NULL) && (notify_2 == NULL))
    133                 goto out_unlock;
    134127
    135128        e = nf_ct_ecache_find(ct);
    136129        if (!e)
    137                 goto out_unlock;
     130                return 0;
    138131
    139132        if (nf_ct_is_confirmed(ct)) {
     
    147140
    148141                if (!((eventmask | missed) & e->ctmask))
    149                         goto out_unlock;
    150 
    151                 ret = min( notify ? notify->fcn(eventmask | missed, &item) : 0,
    152                            notify_2 ? notify_2->fcn(eventmask | missed, &item) : 0 );           
    153                 if (unlikely(ret < 0 || missed)) {
    154                         spin_lock_bh(&ct->lock);
    155                         if (ret < 0) {
    156                                 /* This is a destroy event that has been
    157                                  * triggered by a process, we store the PORTID
    158                                  * to include it in the retransmission.
    159                                  */
    160                                 if (eventmask & (1 << IPCT_DESTROY)) {
    161                                         if (e->portid == 0 && portid != 0)
    162                                                 e->portid = portid;
    163                                         e->state = NFCT_ECACHE_DESTROY_FAIL;
    164                                 } else {
    165                                         e->missed |= eventmask;
    166                                 }
    167                         } else {
    168                                 e->missed &= ~missed;
    169                         }
    170                         spin_unlock_bh(&ct->lock);
    171                 }
    172         }
    173 out_unlock:
    174         rcu_read_unlock();
    175         return ret;
     142                        return 0;
     143
     144                atomic_notifier_call_chain(&net->ct.nf_conntrack_chain, eventmask | missed, &item);
     145        }
     146        return 0;
    176147}
    177148EXPORT_SYMBOL_GPL(nf_conntrack_eventmask_report);
     
    181152void nf_ct_deliver_cached_events(struct nf_conn *ct)
    182153{
    183         struct net *net = nf_ct_net(ct);
    184154        unsigned long events, missed;
    185155        /* Incredibly nasty duplication in order to hack second event */
    186         struct nf_ct_event_notifier *notify;
    187         struct nf_ct_event_notifier *notify_2;
    188156        struct nf_conntrack_ecache *e;
    189157        struct nf_ct_event item;
    190158        int ret;
    191159
    192         rcu_read_lock();
    193         notify = rcu_dereference(net->ct.nf_conntrack_event_cb);
    194         notify_2 = rcu_dereference(net->ct.nf_conntrack_event_cb_2);
    195         if ( (notify == NULL) && (notify_2 == NULL) )
    196                 goto out_unlock;
     160        struct net *net = nf_ct_net(ct);
    197161
    198162        e = nf_ct_ecache_find(ct);
    199163        if (e == NULL)
    200                 goto out_unlock;
     164                return;
    201165
    202166        events = xchg(&e->cache, 0);
    203167
    204168        if (!nf_ct_is_confirmed(ct) || nf_ct_is_dying(ct) || !events)
    205                 goto out_unlock;
     169                return;
    206170
    207171        /* We make a copy of the missed event cache without taking
     
    211175
    212176        if (!((events | missed) & e->ctmask))
    213                 goto out_unlock;
     177                return;
    214178
    215179        item.ct = ct;
     
    217181        item.report = 0;
    218182
    219         ret = min( notify ? notify->fcn(events | missed, &item) : 0,
    220                            notify_2 ? notify_2->fcn(events | missed, &item) : 0);
    221 
    222         if (likely(ret >= 0 && !missed))
    223                 goto out_unlock;
     183        atomic_notifier_call_chain(&net->ct.nf_conntrack_chain,
     184                        events | missed,
     185                        &item);
     186
     187        if (likely(!missed))
     188                return;
    224189
    225190        spin_lock_bh(&ct->lock);
    226         if (ret < 0)
    227                 e->missed |= events;
    228         else
    229                 e->missed &= ~missed;
     191        e->missed &= ~missed;
    230192        spin_unlock_bh(&ct->lock);
    231 
    232 out_unlock:
    233         rcu_read_unlock();
    234193}
    235194EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events);
     
    265224}
    266225
    267 int nf_conntrack_register_notifier(struct net *net,
    268                                    struct nf_ct_event_notifier *new)
    269 {
    270         int ret;
    271         struct nf_ct_event_notifier *notify;
    272         struct nf_ct_event_notifier *notify_2;
    273 
    274         mutex_lock(&nf_ct_ecache_mutex);
    275         notify = rcu_dereference_protected(net->ct.nf_conntrack_event_cb,
    276                                            lockdep_is_held(&nf_ct_ecache_mutex));
    277         notify_2 = rcu_dereference_protected(net->ct.nf_conntrack_event_cb_2,
    278                                            lockdep_is_held(&nf_ct_ecache_mutex));
    279         if ( (notify != NULL) && (notify_2 != NULL) ) {
    280                 ret = -EBUSY;
    281                 goto out_unlock;
    282         }
    283         if (notify == NULL)
    284             rcu_assign_pointer(net->ct.nf_conntrack_event_cb, new);
    285         else
    286             rcu_assign_pointer(net->ct.nf_conntrack_event_cb_2, new);
    287         ret = 0;
    288 
    289 out_unlock:
    290         mutex_unlock(&nf_ct_ecache_mutex);
    291         return ret;
     226int nf_conntrack_register_notifier(struct net *net, struct notifier_block *nb)
     227{
     228        return atomic_notifier_chain_register(&net->ct.nf_conntrack_chain, nb);
    292229}
    293230EXPORT_SYMBOL_GPL(nf_conntrack_register_notifier);
    294231
    295 void nf_conntrack_unregister_notifier(struct net *net,
    296                                       struct nf_ct_event_notifier *new)
    297 {
    298         struct nf_ct_event_notifier *notify;
    299         struct nf_ct_event_notifier *notify_2;
    300 
    301         mutex_lock(&nf_ct_ecache_mutex);
    302         notify = rcu_dereference_protected(net->ct.nf_conntrack_event_cb,
    303                                            lockdep_is_held(&nf_ct_ecache_mutex));
    304         notify_2 = rcu_dereference_protected(net->ct.nf_conntrack_event_cb_2,
    305                                            lockdep_is_held(&nf_ct_ecache_mutex));
    306         BUG_ON((notify != new) || (notify_2 != new));
    307         if (notify == new)
    308             RCU_INIT_POINTER(net->ct.nf_conntrack_event_cb, NULL);
    309         else
    310             RCU_INIT_POINTER(net->ct.nf_conntrack_event_cb_2, NULL);
    311         mutex_unlock(&nf_ct_ecache_mutex);
     232int nf_conntrack_unregister_notifier(struct net *net, struct notifier_block *nb)
     233{
     234        return atomic_notifier_chain_unregister(&net->ct.nf_conntrack_chain, nb);
    312235}
    313236EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier);
  • src/linux/universal/linux-4.9/net/netfilter/nf_conntrack_netlink.c

    r32569 r32623  
    2929#include <linux/spinlock.h>
    3030#include <linux/interrupt.h>
     31#include <linux/notifier.h>
    3132#include <linux/slab.h>
    3233
     
    616617}
    617618
    618 static int
    619 ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item)
     619static int ctnetlink_conntrack_event(struct notifier_block *this,
     620                                     unsigned long events, void *ptr)
    620621{
    621622        const struct nf_conntrack_zone *zone;
     
    624625        struct nfgenmsg *nfmsg;
    625626        struct nlattr *nest_parms;
     627        struct nf_ct_event *item = ptr;
    626628        struct nf_conn *ct = item->ct;
    627629        struct sk_buff *skb;
     
    32613263
    32623264#ifdef CONFIG_NF_CONNTRACK_EVENTS
    3263 static struct nf_ct_event_notifier ctnl_notifier = {
    3264         .fcn = ctnetlink_conntrack_event,
     3265static struct notifier_block ctnl_notifier = {
     3266        .notifier_call = ctnetlink_conntrack_event,
    32653267};
    32663268
Note: See TracChangeset for help on using the changeset viewer.