Changeset 32717


Ignore:
Timestamp:
Jul 16, 2017, 10:01:40 PM (10 days ago)
Author:
brainslayer
Message:

remerge code

Location:
src/linux/universal
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • src/linux/universal/linux-3.10/net/shortcut-fe/fast-classifier.c

    r32716 r32717  
    44 *      fast-classifier
    55 *
    6  * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
     6 * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved.
    77 * Permission to use, copy, modify, and/or distribute this software for
    88 * any purpose with or without fee is hereby granted, provided that the
     
    257257                ret = sfe_ipv4_recv(dev, skb);
    258258
    259         } 
     259        }
    260260#ifdef SFE_SUPPORT_IPV6
    261 
    262261        else if (likely(htons(ETH_P_IPV6) == skb->protocol)) {
    263262                struct inet6_dev *in_dev;
     
    283282                ret = sfe_ipv6_recv(dev, skb);
    284283
    285         } 
     284        }
    286285#endif
    287286        else {
     
    380379}
    381380
    382 
    383381static DEFINE_SPINLOCK(sfe_connections_lock);
    384382
     
    388386        struct nf_conn *ct;
    389387        int hits;
     388        int offload_permit;
    390389        int offloaded;
    391390        bool is_v4;
     
    471470        struct sk_buff *skb;
    472471        int rc;
     472        int buf_len;
     473        int total_len;
    473474        void *msg_head;
    474475
    475         skb = genlmsg_new(sizeof(*fc_msg) + fast_classifier_gnl_family.hdrsize,
    476                           GFP_ATOMIC);
     476        /*
     477         * Calculate our packet payload size.
     478         * Start with our family header.
     479         */
     480        buf_len = fast_classifier_gnl_family.hdrsize;
     481
     482        /*
     483         * Add the nla_total_size of each attribute we're going to nla_put().
     484         */
     485        buf_len += nla_total_size(sizeof(*fc_msg));
     486
     487        /*
     488         * Lastly we need to add space for the NL message header since
     489         * genlmsg_new only accounts for the GENL header and not the
     490         * outer NL header. To do this, we use a NL helper function which
     491         * calculates the total size of a netlink message given a payload size.
     492         * Note this value does not include the GENL header, but that's
     493         * added automatically by genlmsg_new.
     494         */
     495        total_len = nlmsg_total_size(buf_len);
     496        skb = genlmsg_new(total_len, GFP_ATOMIC);
    477497        if (!skb)
    478498                return;
     
    491511        }
    492512
    493         genlmsg_end(skb, msg_head);
     513#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 19 , 0))
     514        rc = genlmsg_end(skb, msg_head);
    494515        if (rc < 0) {
    495516                genlmsg_cancel(skb, msg_head);
     
    497518                return;
    498519        }
     520#else
     521        genlmsg_end(skb, msg_head);
     522
     523#endif
    499524
    500525#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
     
    524549
    525550        DEBUG_TRACE("Notify NL message %d ", msg);
    526         DEBUG_TRACE("sip=%pIS dip=%pIS ", &fc_msg->src_saddr, &fc_msg->dst_saddr);
     551        if (fc_msg->ethertype == AF_INET) {
     552                DEBUG_TRACE("sip=%pI4 dip=%pI4 ", &fc_msg->src_saddr, &fc_msg->dst_saddr);
     553        } else {
     554                DEBUG_TRACE("sip=%pI6 dip=%pI6 ", &fc_msg->src_saddr, &fc_msg->dst_saddr);
     555        }
    527556        DEBUG_TRACE("protocol=%d sport=%d dport=%d smac=%pM dmac=%pM\n",
    528557                    fc_msg->proto, fc_msg->sport, fc_msg->dport, fc_msg->smac, fc_msg->dmac);
     
    542571        struct sfe_connection *conn;
    543572        u32 key;
     573#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0))
     574        struct hlist_node *node;
     575#endif
    544576
    545577        key = fc_conn_hash(saddr, daddr, sport, dport, is_v4);
    546578
    547         sfe_hash_for_each_possible(fc_conn_ht, conn, hl, key) {
     579        sfe_hash_for_each_possible(fc_conn_ht, conn, node, hl, key) {
    548580                if (conn->is_v4 != is_v4) {
    549581                        continue;
     
    579611        struct sfe_connection *conn;
    580612        u32 key;
     613#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0))
     614        struct hlist_node *node;
     615#endif
    581616
    582617        key = fc_conn_hash(saddr, daddr, sport, dport, is_v4);
    583618
    584         sfe_hash_for_each_possible(fc_conn_ht, conn, hl, key) {
     619        sfe_hash_for_each_possible(fc_conn_ht, conn, node, hl, key) {
    585620                if (conn->is_v4 != is_v4) {
    586621                        continue;
     
    603638        key = fc_conn_hash(daddr, saddr, dport, sport, is_v4);
    604639
    605         sfe_hash_for_each_possible(fc_conn_ht, conn, hl, key) {
     640        sfe_hash_for_each_possible(fc_conn_ht, conn, node, hl, key) {
    606641                if (conn->is_v4 != is_v4) {
    607642                        continue;
     
    651686        DEBUG_TRACE(" -> adding item to sfe_connections, new size: %d\n", sfe_connections_size);
    652687
    653         DEBUG_TRACE("new offloadable: key: %u proto: %d src_ip: %pIS dst_ip: %pIS, src_port: %d, dst_port: %d\n",
    654                 key, sic->protocol, &(sic->src_ip), &(sic->dest_ip), sic->src_port, sic->dest_port);
     688        if (conn->is_v4) {
     689                DEBUG_TRACE("new offloadable: key: %u proto: %d src_ip: %pI4 dst_ip: %pI4, src_port: %d, dst_port: %d\n",
     690                                key, sic->protocol, &(sic->src_ip), &(sic->dest_ip), sic->src_port, sic->dest_port);
     691        } else {
     692                DEBUG_TRACE("new offloadable: key: %u proto: %d src_ip: %pI6 dst_ip: %pI6, src_port: %d, dst_port: %d\n",
     693                                key, sic->protocol, &(sic->src_ip), &(sic->dest_ip), sic->src_port, sic->dest_port);
     694        }
    655695
    656696        return conn;
     
    664704fast_classifier_offload_genl_msg(struct sk_buff *skb, struct genl_info *info)
    665705{
    666         int ret;
    667706        struct nlattr *na;
    668707        struct fast_classifier_tuple *fc_msg;
     
    672711        fc_msg = nla_data(na);
    673712
    674         DEBUG_TRACE("want to offload: %d-%d, %pIS, %pIS, %d, %d SMAC=%pM DMAC=%pM\n" :
    675                 fc_msg->ethertype,
    676                 fc_msg->proto,
    677                 &fc_msg->src_saddr,
    678                 &fc_msg->dst_saddr,
    679                 fc_msg->sport,
    680                 fc_msg->dport,
    681                 fc_msg->smac,
    682                 fc_msg->dmac);
     713        DEBUG_TRACE((fc_msg->ethertype == AF_INET ?
     714                "want to offload: %d-%d, %pI4, %pI4, %d, %d SMAC=%pM DMAC=%pM\n" :
     715                "want to offload: %d-%d, %pI6, %pI6, %d, %d SMAC=%pM DMAC=%pM\n"),
     716                    fc_msg->ethertype,
     717                    fc_msg->proto,
     718                    &fc_msg->src_saddr,
     719                    &fc_msg->dst_saddr,
     720                    fc_msg->sport,
     721                    fc_msg->dport,
     722                    fc_msg->smac,
     723                    fc_msg->dmac);
    683724
    684725        spin_lock_bh(&sfe_connections_lock);
     
    696737        }
    697738
    698         if (conn->offloaded != 0) {
    699                 spin_unlock_bh(&sfe_connections_lock);
    700                 DEBUG_TRACE("GOT REQUEST TO OFFLOAD ALREADY OFFLOADED CONN FROM USERSPACE\n");
    701                 return 0;
    702         }
    703 
    704         DEBUG_TRACE("USERSPACE OFFLOAD REQUEST, MATCH FOUND, WILL OFFLOAD\n");
    705         if (fast_classifier_update_protocol(conn->sic, conn->ct) == 0) {
    706                 spin_unlock_bh(&sfe_connections_lock);
    707                 DEBUG_TRACE("UNKNOWN PROTOCOL OR CONNECTION CLOSING, SKIPPING\n");
    708                 return 0;
    709         }
     739        conn->offload_permit = 1;
     740        spin_unlock_bh(&sfe_connections_lock);
     741        atomic_inc(&offload_msgs);
    710742
    711743        DEBUG_TRACE("INFO: calling sfe rule creation!\n");
    712         spin_unlock_bh(&sfe_connections_lock);
    713         ret = conn->is_v4 ? sfe_ipv4_create_rule(conn->sic) : sfe_ipv6_create_rule(conn->sic);
    714         if ((ret == 0) || (ret == -EADDRINUSE)) {
    715                 conn->offloaded = 1;
    716                 fast_classifier_send_genl_msg(FAST_CLASSIFIER_C_OFFLOADED,
    717                                               fc_msg);
    718         }
    719 
    720         atomic_inc(&offload_msgs);
    721744        return 0;
    722745}
     
    837860         * Get addressing information, non-NAT first
    838861         */
    839         if (is_v4) {
     862        if (likely(is_v4)) {
    840863                u32 dscp;
    841864
     
    892915        }
    893916#endif
     917
    894918        switch (sic.protocol) {
    895919        case IPPROTO_TCP:
     
    937961        }
    938962
    939         DEBUG_TRACE("POST_ROUTE: checking new connection: %d src_ip: %pIS dst_ip: %pIS, src_port: %d, dst_port: %d\n",
    940                 sic.protocol, &sic.src_ip, &sic.dest_ip, sic.src_port, sic.dest_port);
     963        if (is_v4) {
     964                DEBUG_TRACE("POST_ROUTE: checking new connection: %d src_ip: %pI4 dst_ip: %pI4, src_port: %d, dst_port: %d\n",
     965                            sic.protocol, &sic.src_ip, &sic.dest_ip, sic.src_port, sic.dest_port);
     966        } else {
     967                DEBUG_TRACE("POST_ROUTE: checking new connection: %d src_ip: %pI6 dst_ip: %pI6, src_port: %d, dst_port: %d\n",
     968                            sic.protocol, &sic.src_ip, &sic.dest_ip, sic.src_port, sic.dest_port);
     969        }
    941970
    942971        /*
     
    951980
    952981                if (!conn->offloaded) {
    953                         if (conn->hits >= offload_at_pkts) {
     982                        if (conn->offload_permit || conn->hits >= offload_at_pkts) {
    954983                                DEBUG_TRACE("OFFLOADING CONNECTION, TOO MANY HITS\n");
    955984
     
    9721001                                                fc_msg.src_saddr.in = *((struct in_addr *)&sic.src_ip);
    9731002                                                fc_msg.dst_saddr.in = *((struct in_addr *)&sic.dest_ip_xlate);
    974                                         } else {
     1003                                        }
     1004#ifdef SFE_SUPPORT_IPV6
     1005                                        else {
    9751006                                                fc_msg.ethertype = AF_INET6;
    9761007                                                fc_msg.src_saddr.in6 = *((struct in6_addr *)&sic.src_ip);
    9771008                                                fc_msg.dst_saddr.in6 = *((struct in6_addr *)&sic.dest_ip_xlate);
    9781009                                        }
    979 
     1010#endif
    9801011                                        fc_msg.proto = sic.protocol;
    9811012                                        fc_msg.sport = sic.src_port;
     
    10741105        }
    10751106        conn->hits = 0;
     1107        conn->offload_permit = 0;
    10761108        conn->offloaded = 0;
    10771109        conn->is_v4 = is_v4;
     
    11271159
    11281160#ifdef SFE_SUPPORT_IPV6
     1161
    11291162/*
    11301163 * fast_classifier_ipv6_post_routing_hook()
     
    12061239                sid.dest_ip.ip6[0] = *((struct sfe_ipv6_addr *)&orig_tuple.dst.u3.in6);
    12071240                is_v4 = false;
    1208         } 
     1241        }
    12091242#endif
    12101243        else {
     
    12541287        }
    12551288
    1256         DEBUG_TRACE("Try to clean up: proto: %d src_ip: %pIS dst_ip: %pIS, src_port: %d, dst_port: %d\n",
    1257                 sid.protocol, &sid.src_ip, &sid.dest_ip, sid.src_port, sid.dest_port);
     1289        if (is_v4) {
     1290                DEBUG_TRACE("Try to clean up: proto: %d src_ip: %pI4 dst_ip: %pI4, src_port: %d, dst_port: %d\n",
     1291                            sid.protocol, &sid.src_ip, &sid.dest_ip, sid.src_port, sid.dest_port);
     1292        } else {
     1293                DEBUG_TRACE("Try to clean up: proto: %d src_ip: %pI6 dst_ip: %pI6, src_port: %d, dst_port: %d\n",
     1294                            sid.protocol, &sid.src_ip, &sid.dest_ip, sid.src_port, sid.dest_port);
     1295        }
    12581296
    12591297        spin_lock_bh(&sfe_connections_lock);
     
    12651303                        fc_msg.src_saddr.in = *((struct in_addr *)&conn->sic->src_ip);
    12661304                        fc_msg.dst_saddr.in = *((struct in_addr *)&conn->sic->dest_ip_xlate);
    1267                 } else {
     1305                } else
     1306#ifdef SFE_SUPPORT_IPV6
     1307                {
    12681308                        fc_msg.ethertype = AF_INET6;
    12691309                        fc_msg.src_saddr.in6 = *((struct in6_addr *)&conn->sic->src_ip);
    12701310                        fc_msg.dst_saddr.in6 = *((struct in6_addr *)&conn->sic->dest_ip_xlate);
    12711311                }
    1272 
     1312#endif
    12731313                fc_msg.proto = conn->sic->protocol;
    12741314                fc_msg.sport = conn->sic->src_port;
     
    13431383        tuple.dst.u.all = (__be16)sis->dest_port;
    13441384
     1385#ifdef SFE_SUPPORT_IPV6
    13451386        if (sis->is_v6) {
    13461387                tuple.src.u3.in6 = *((struct in6_addr *)sis->src_ip.ip6);
     
    13521393                            &tuple.src.u3.in6, (unsigned int)ntohs(tuple.src.u.all),
    13531394                            &tuple.dst.u3.in6, (unsigned int)ntohs(tuple.dst.u.all));
    1354         } else {
     1395        } else
     1396#endif
     1397        {
    13551398                tuple.src.u3.ip = sis->src_ip.ip;
    13561399                tuple.dst.u3.ip = sis->dest_ip.ip;
     
    14131456        if (acct) {
    14141457                spin_lock_bh(&ct->lock);
    1415                 atomic64_set(&SFE_ACCT_COUNTER(acct)[IP_CT_DIR_ORIGINAL].packets, sis->src_packet_count);
    1416                 atomic64_set(&SFE_ACCT_COUNTER(acct)[IP_CT_DIR_ORIGINAL].bytes, sis->src_byte_count);
    1417                 atomic64_set(&SFE_ACCT_COUNTER(acct)[IP_CT_DIR_REPLY].packets, sis->dest_packet_count);
    1418                 atomic64_set(&SFE_ACCT_COUNTER(acct)[IP_CT_DIR_REPLY].bytes, sis->dest_byte_count);
     1458                atomic64_add(sis->src_new_packet_count, &SFE_ACCT_COUNTER(acct)[IP_CT_DIR_ORIGINAL].packets);
     1459                atomic64_add(sis->src_new_byte_count, &SFE_ACCT_COUNTER(acct)[IP_CT_DIR_ORIGINAL].bytes);
     1460                atomic64_add(sis->dest_new_packet_count, &SFE_ACCT_COUNTER(acct)[IP_CT_DIR_REPLY].packets);
     1461                atomic64_add(sis->dest_new_byte_count, &SFE_ACCT_COUNTER(acct)[IP_CT_DIR_REPLY].bytes);
    14191462                spin_unlock_bh(&ct->lock);
    14201463        }
     
    14641507#endif
    14651508        }
     1509
    14661510        return NOTIFY_DONE;
    14671511}
     
    14771521                sfe_ipv4_destroy_all_rules_for_dev(dev);
    14781522        }
     1523
    14791524        return NOTIFY_DONE;
    14801525}
    14811526
     1527#ifdef SFE_SUPPORT_IPV6
    14821528/*
    14831529 * fast_classifier_inet6_event()
     
    14901536                sfe_ipv6_destroy_all_rules_for_dev(dev);
    14911537        }
     1538
    14921539        return NOTIFY_DONE;
    14931540}
    1494 
    1495 
     1541#endif
    14961542/*
    14971543 * fast_classifier_get_offload_at_pkts()
     
    15331579        struct sfe_connection *conn;
    15341580        u32 i;
     1581#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0))
     1582        struct hlist_node *node;
     1583#endif
    15351584
    15361585        spin_lock_bh(&sfe_connections_lock);
     
    15441593                        atomic_read(&offloaded_fail_msgs),
    15451594                        atomic_read(&done_fail_msgs));
    1546         sfe_hash_for_each(fc_conn_ht, i, conn, hl) {
     1595        sfe_hash_for_each(fc_conn_ht, i, node, conn, hl) {
    15471596                len += scnprintf(buf + len, PAGE_SIZE - len,
    15481597                                (conn->is_v4 ? "o=%d, p=%d [%pM]:%pI4:%u %pI4:%u:[%pM] m=%08x h=%d\n" : "o=%d, p=%d [%pM]:%pI6:%u %pI6:%u:[%pM] m=%08x h=%d\n"),
     
    16171666 * sysfs attributes.
    16181667 */
    1619 static const struct device_attribute fast_classifier_attrs[] = {
    1620         __ATTR(offload_at_pkts, S_IWUSR | S_IRUGO, fast_classifier_get_offload_at_pkts, fast_classifier_set_offload_at_pkts),
    1621         __ATTR(debug_info, S_IRUGO, fast_classifier_get_debug_info, NULL),
    1622         __ATTR(skip_to_bridge_ingress, S_IWUSR | S_IRUGO, fast_classifier_get_skip_bridge_ingress, fast_classifier_set_skip_bridge_ingress),
    1623         __ATTR(exceptions, S_IRUGO, fast_classifier_get_exceptions, NULL),
    1624 };
     1668static const struct device_attribute fast_classifier_offload_at_pkts_attr =
     1669        __ATTR(offload_at_pkts, S_IWUSR | S_IRUGO, fast_classifier_get_offload_at_pkts, fast_classifier_set_offload_at_pkts);
     1670static const struct device_attribute fast_classifier_debug_info_attr =
     1671        __ATTR(debug_info, S_IRUGO, fast_classifier_get_debug_info, NULL);
     1672static const struct device_attribute fast_classifier_skip_bridge_ingress =
     1673        __ATTR(skip_to_bridge_ingress, S_IWUSR | S_IRUGO, fast_classifier_get_skip_bridge_ingress, fast_classifier_set_skip_bridge_ingress);
     1674static const struct device_attribute fast_classifier_exceptions_attr =
     1675        __ATTR(exceptions, S_IRUGO, fast_classifier_get_exceptions, NULL);
    16251676
    16261677/*
     
    16311682        struct fast_classifier *sc = &__fsc;
    16321683        int result = -1;
    1633         size_t i, j;
    16341684
    16351685        printk(KERN_ALERT "fast-classifier: starting up\n");
     
    16471697        }
    16481698
    1649         for (i = 0; i < ARRAY_SIZE(fast_classifier_attrs); i++) {
    1650                 result = sysfs_create_file(sc->sys_fast_classifier, &fast_classifier_attrs[i].attr);
    1651                 if (result) {
    1652                         DEBUG_ERROR("failed to register %s : %d\n",
    1653                                     fast_classifier_attrs[i].attr.name, result);
    1654                         goto exit2;
    1655                 }
     1699        result = sysfs_create_file(sc->sys_fast_classifier, &fast_classifier_offload_at_pkts_attr.attr);
     1700        if (result) {
     1701                DEBUG_ERROR("failed to register offload at pkgs: %d\n", result);
     1702                goto exit2;
     1703        }
     1704
     1705        result = sysfs_create_file(sc->sys_fast_classifier, &fast_classifier_debug_info_attr.attr);
     1706        if (result) {
     1707                DEBUG_ERROR("failed to register debug dev: %d\n", result);
     1708                sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_offload_at_pkts_attr.attr);
     1709                goto exit2;
     1710        }
     1711
     1712        result = sysfs_create_file(sc->sys_fast_classifier, &fast_classifier_skip_bridge_ingress.attr);
     1713        if (result) {
     1714                DEBUG_ERROR("failed to register skip bridge on ingress: %d\n", result);
     1715                sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_offload_at_pkts_attr.attr);
     1716                sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_debug_info_attr.attr);
     1717                goto exit2;
     1718        }
     1719
     1720        result = sysfs_create_file(sc->sys_fast_classifier, &fast_classifier_exceptions_attr.attr);
     1721        if (result) {
     1722                DEBUG_ERROR("failed to register exceptions file: %d\n", result);
     1723                sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_offload_at_pkts_attr.attr);
     1724                sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_debug_info_attr.attr);
     1725                sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_skip_bridge_ingress.attr);
     1726                goto exit2;
    16561727        }
    16571728
     
    17581829#endif
    17591830        unregister_netdevice_notifier(&sc->dev_notifier);
     1831        sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_offload_at_pkts_attr.attr);
     1832        sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_debug_info_attr.attr);
     1833        sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_skip_bridge_ingress.attr);
     1834        sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_exceptions_attr.attr);
    17601835
    17611836exit2:
    1762         for (j = 0; j < i; j++) {
    1763                 sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_attrs[j].attr);
    1764         }
    17651837        kobject_put(sc->sys_fast_classifier);
    17661838
     
    18051877        sfe_ipv6_destroy_all_rules_for_dev(NULL);
    18061878#endif
    1807 
    18081879
    18091880#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0))
     
    18341905        kobject_put(sc->sys_fast_classifier);
    18351906}
    1836 
  • src/linux/universal/linux-3.10/net/shortcut-fe/sfe_backport.h

    r32708 r32717  
    134134#endif
    135135
    136 #define sfe_hash_for_each_possible(name, obj, member, key) \
     136#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
     137#define sfe_hash_for_each_possible(name, obj, node, member, key) \
    137138        hash_for_each_possible(name, obj, member, key)
     139#else
     140#define sfe_hash_for_each_possible(name, obj, node, member, key) \
     141        hash_for_each_possible(name, obj, node, member, key)
     142#endif
    138143
    139 #define sfe_hash_for_each(name, bkt, obj, member) \
     144#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
     145#define sfe_hash_for_each(name, bkt, node, obj, member) \
    140146        hash_for_each(name, bkt, obj, member)
     147#else
     148#define sfe_hash_for_each(name, bkt, node, obj, member) \
     149        hash_for_each(name, bkt, node, obj, member)
     150#endif
     151
     152#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
     153#define sfe_dst_get_neighbour(dst, daddr) dst_neigh_lookup(dst, addr)
     154#else
     155static inline struct neighbour *
     156sfe_dst_get_neighbour(struct dst_entry *dst, void *daddr)
     157{
     158        struct neighbour *neigh = dst_get_neighbour_noref(dst);
     159
     160        if (neigh)
     161                neigh_hold(neigh);
     162
     163        return neigh;
     164}
     165#endif
     166
    141167
    142168#endif
  • src/linux/universal/linux-3.18/net/shortcut-fe/fast-classifier.c

    r32716 r32717  
    44 *      fast-classifier
    55 *
    6  * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
     6 * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved.
    77 * Permission to use, copy, modify, and/or distribute this software for
    88 * any purpose with or without fee is hereby granted, provided that the
     
    257257                ret = sfe_ipv4_recv(dev, skb);
    258258
    259         } 
     259        }
    260260#ifdef SFE_SUPPORT_IPV6
    261 
    262261        else if (likely(htons(ETH_P_IPV6) == skb->protocol)) {
    263262                struct inet6_dev *in_dev;
     
    283282                ret = sfe_ipv6_recv(dev, skb);
    284283
    285         } 
     284        }
    286285#endif
    287286        else {
     
    380379}
    381380
    382 
    383381static DEFINE_SPINLOCK(sfe_connections_lock);
    384382
     
    388386        struct nf_conn *ct;
    389387        int hits;
     388        int offload_permit;
    390389        int offloaded;
    391390        bool is_v4;
     
    471470        struct sk_buff *skb;
    472471        int rc;
     472        int buf_len;
     473        int total_len;
    473474        void *msg_head;
    474475
    475         skb = genlmsg_new(sizeof(*fc_msg) + fast_classifier_gnl_family.hdrsize,
    476                           GFP_ATOMIC);
     476        /*
     477         * Calculate our packet payload size.
     478         * Start with our family header.
     479         */
     480        buf_len = fast_classifier_gnl_family.hdrsize;
     481
     482        /*
     483         * Add the nla_total_size of each attribute we're going to nla_put().
     484         */
     485        buf_len += nla_total_size(sizeof(*fc_msg));
     486
     487        /*
     488         * Lastly we need to add space for the NL message header since
     489         * genlmsg_new only accounts for the GENL header and not the
     490         * outer NL header. To do this, we use a NL helper function which
     491         * calculates the total size of a netlink message given a payload size.
     492         * Note this value does not include the GENL header, but that's
     493         * added automatically by genlmsg_new.
     494         */
     495        total_len = nlmsg_total_size(buf_len);
     496        skb = genlmsg_new(total_len, GFP_ATOMIC);
    477497        if (!skb)
    478498                return;
     
    491511        }
    492512
    493         genlmsg_end(skb, msg_head);
     513#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 19 , 0))
     514        rc = genlmsg_end(skb, msg_head);
    494515        if (rc < 0) {
    495516                genlmsg_cancel(skb, msg_head);
     
    497518                return;
    498519        }
     520#else
     521        genlmsg_end(skb, msg_head);
     522
     523#endif
    499524
    500525#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
     
    524549
    525550        DEBUG_TRACE("Notify NL message %d ", msg);
    526         DEBUG_TRACE("sip=%pIS dip=%pIS ", &fc_msg->src_saddr, &fc_msg->dst_saddr);
     551        if (fc_msg->ethertype == AF_INET) {
     552                DEBUG_TRACE("sip=%pI4 dip=%pI4 ", &fc_msg->src_saddr, &fc_msg->dst_saddr);
     553        } else {
     554                DEBUG_TRACE("sip=%pI6 dip=%pI6 ", &fc_msg->src_saddr, &fc_msg->dst_saddr);
     555        }
    527556        DEBUG_TRACE("protocol=%d sport=%d dport=%d smac=%pM dmac=%pM\n",
    528557                    fc_msg->proto, fc_msg->sport, fc_msg->dport, fc_msg->smac, fc_msg->dmac);
     
    542571        struct sfe_connection *conn;
    543572        u32 key;
     573#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0))
     574        struct hlist_node *node;
     575#endif
    544576
    545577        key = fc_conn_hash(saddr, daddr, sport, dport, is_v4);
    546578
    547         sfe_hash_for_each_possible(fc_conn_ht, conn, hl, key) {
     579        sfe_hash_for_each_possible(fc_conn_ht, conn, node, hl, key) {
    548580                if (conn->is_v4 != is_v4) {
    549581                        continue;
     
    579611        struct sfe_connection *conn;
    580612        u32 key;
     613#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0))
     614        struct hlist_node *node;
     615#endif
    581616
    582617        key = fc_conn_hash(saddr, daddr, sport, dport, is_v4);
    583618
    584         sfe_hash_for_each_possible(fc_conn_ht, conn, hl, key) {
     619        sfe_hash_for_each_possible(fc_conn_ht, conn, node, hl, key) {
    585620                if (conn->is_v4 != is_v4) {
    586621                        continue;
     
    603638        key = fc_conn_hash(daddr, saddr, dport, sport, is_v4);
    604639
    605         sfe_hash_for_each_possible(fc_conn_ht, conn, hl, key) {
     640        sfe_hash_for_each_possible(fc_conn_ht, conn, node, hl, key) {
    606641                if (conn->is_v4 != is_v4) {
    607642                        continue;
     
    651686        DEBUG_TRACE(" -> adding item to sfe_connections, new size: %d\n", sfe_connections_size);
    652687
    653         DEBUG_TRACE("new offloadable: key: %u proto: %d src_ip: %pIS dst_ip: %pIS, src_port: %d, dst_port: %d\n",
    654                 key, sic->protocol, &(sic->src_ip), &(sic->dest_ip), sic->src_port, sic->dest_port);
     688        if (conn->is_v4) {
     689                DEBUG_TRACE("new offloadable: key: %u proto: %d src_ip: %pI4 dst_ip: %pI4, src_port: %d, dst_port: %d\n",
     690                                key, sic->protocol, &(sic->src_ip), &(sic->dest_ip), sic->src_port, sic->dest_port);
     691        } else {
     692                DEBUG_TRACE("new offloadable: key: %u proto: %d src_ip: %pI6 dst_ip: %pI6, src_port: %d, dst_port: %d\n",
     693                                key, sic->protocol, &(sic->src_ip), &(sic->dest_ip), sic->src_port, sic->dest_port);
     694        }
    655695
    656696        return conn;
     
    664704fast_classifier_offload_genl_msg(struct sk_buff *skb, struct genl_info *info)
    665705{
    666         int ret;
    667706        struct nlattr *na;
    668707        struct fast_classifier_tuple *fc_msg;
     
    672711        fc_msg = nla_data(na);
    673712
    674         DEBUG_TRACE("want to offload: %d-%d, %pIS, %pIS, %d, %d SMAC=%pM DMAC=%pM\n" :
    675                 fc_msg->ethertype,
    676                 fc_msg->proto,
    677                 &fc_msg->src_saddr,
    678                 &fc_msg->dst_saddr,
    679                 fc_msg->sport,
    680                 fc_msg->dport,
    681                 fc_msg->smac,
    682                 fc_msg->dmac);
     713        DEBUG_TRACE((fc_msg->ethertype == AF_INET ?
     714                "want to offload: %d-%d, %pI4, %pI4, %d, %d SMAC=%pM DMAC=%pM\n" :
     715                "want to offload: %d-%d, %pI6, %pI6, %d, %d SMAC=%pM DMAC=%pM\n"),
     716                    fc_msg->ethertype,
     717                    fc_msg->proto,
     718                    &fc_msg->src_saddr,
     719                    &fc_msg->dst_saddr,
     720                    fc_msg->sport,
     721                    fc_msg->dport,
     722                    fc_msg->smac,
     723                    fc_msg->dmac);
    683724
    684725        spin_lock_bh(&sfe_connections_lock);
     
    696737        }
    697738
    698         if (conn->offloaded != 0) {
    699                 spin_unlock_bh(&sfe_connections_lock);
    700                 DEBUG_TRACE("GOT REQUEST TO OFFLOAD ALREADY OFFLOADED CONN FROM USERSPACE\n");
    701                 return 0;
    702         }
    703 
    704         DEBUG_TRACE("USERSPACE OFFLOAD REQUEST, MATCH FOUND, WILL OFFLOAD\n");
    705         if (fast_classifier_update_protocol(conn->sic, conn->ct) == 0) {
    706                 spin_unlock_bh(&sfe_connections_lock);
    707                 DEBUG_TRACE("UNKNOWN PROTOCOL OR CONNECTION CLOSING, SKIPPING\n");
    708                 return 0;
    709         }
     739        conn->offload_permit = 1;
     740        spin_unlock_bh(&sfe_connections_lock);
     741        atomic_inc(&offload_msgs);
    710742
    711743        DEBUG_TRACE("INFO: calling sfe rule creation!\n");
    712         spin_unlock_bh(&sfe_connections_lock);
    713         ret = conn->is_v4 ? sfe_ipv4_create_rule(conn->sic) : sfe_ipv6_create_rule(conn->sic);
    714         if ((ret == 0) || (ret == -EADDRINUSE)) {
    715                 conn->offloaded = 1;
    716                 fast_classifier_send_genl_msg(FAST_CLASSIFIER_C_OFFLOADED,
    717                                               fc_msg);
    718         }
    719 
    720         atomic_inc(&offload_msgs);
    721744        return 0;
    722745}
     
    837860         * Get addressing information, non-NAT first
    838861         */
    839         if (is_v4) {
     862        if (likely(is_v4)) {
    840863                u32 dscp;
    841864
     
    892915        }
    893916#endif
     917
    894918        switch (sic.protocol) {
    895919        case IPPROTO_TCP:
     
    937961        }
    938962
    939         DEBUG_TRACE("POST_ROUTE: checking new connection: %d src_ip: %pIS dst_ip: %pIS, src_port: %d, dst_port: %d\n",
    940                 sic.protocol, &sic.src_ip, &sic.dest_ip, sic.src_port, sic.dest_port);
     963        if (is_v4) {
     964                DEBUG_TRACE("POST_ROUTE: checking new connection: %d src_ip: %pI4 dst_ip: %pI4, src_port: %d, dst_port: %d\n",
     965                            sic.protocol, &sic.src_ip, &sic.dest_ip, sic.src_port, sic.dest_port);
     966        } else {
     967                DEBUG_TRACE("POST_ROUTE: checking new connection: %d src_ip: %pI6 dst_ip: %pI6, src_port: %d, dst_port: %d\n",
     968                            sic.protocol, &sic.src_ip, &sic.dest_ip, sic.src_port, sic.dest_port);
     969        }
    941970
    942971        /*
     
    951980
    952981                if (!conn->offloaded) {
    953                         if (conn->hits >= offload_at_pkts) {
     982                        if (conn->offload_permit || conn->hits >= offload_at_pkts) {
    954983                                DEBUG_TRACE("OFFLOADING CONNECTION, TOO MANY HITS\n");
    955984
     
    9721001                                                fc_msg.src_saddr.in = *((struct in_addr *)&sic.src_ip);
    9731002                                                fc_msg.dst_saddr.in = *((struct in_addr *)&sic.dest_ip_xlate);
    974                                         } else {
     1003                                        }
     1004#ifdef SFE_SUPPORT_IPV6
     1005                                        else {
    9751006                                                fc_msg.ethertype = AF_INET6;
    9761007                                                fc_msg.src_saddr.in6 = *((struct in6_addr *)&sic.src_ip);
    9771008                                                fc_msg.dst_saddr.in6 = *((struct in6_addr *)&sic.dest_ip_xlate);
    9781009                                        }
    979 
     1010#endif
    9801011                                        fc_msg.proto = sic.protocol;
    9811012                                        fc_msg.sport = sic.src_port;
     
    10741105        }
    10751106        conn->hits = 0;
     1107        conn->offload_permit = 0;
    10761108        conn->offloaded = 0;
    10771109        conn->is_v4 = is_v4;
     
    11271159
    11281160#ifdef SFE_SUPPORT_IPV6
     1161
    11291162/*
    11301163 * fast_classifier_ipv6_post_routing_hook()
     
    12061239                sid.dest_ip.ip6[0] = *((struct sfe_ipv6_addr *)&orig_tuple.dst.u3.in6);
    12071240                is_v4 = false;
    1208         } 
     1241        }
    12091242#endif
    12101243        else {
     
    12541287        }
    12551288
    1256         DEBUG_TRACE("Try to clean up: proto: %d src_ip: %pIS dst_ip: %pIS, src_port: %d, dst_port: %d\n",
    1257                 sid.protocol, &sid.src_ip, &sid.dest_ip, sid.src_port, sid.dest_port);
     1289        if (is_v4) {
     1290                DEBUG_TRACE("Try to clean up: proto: %d src_ip: %pI4 dst_ip: %pI4, src_port: %d, dst_port: %d\n",
     1291                            sid.protocol, &sid.src_ip, &sid.dest_ip, sid.src_port, sid.dest_port);
     1292        } else {
     1293                DEBUG_TRACE("Try to clean up: proto: %d src_ip: %pI6 dst_ip: %pI6, src_port: %d, dst_port: %d\n",
     1294                            sid.protocol, &sid.src_ip, &sid.dest_ip, sid.src_port, sid.dest_port);
     1295        }
    12581296
    12591297        spin_lock_bh(&sfe_connections_lock);
     
    12651303                        fc_msg.src_saddr.in = *((struct in_addr *)&conn->sic->src_ip);
    12661304                        fc_msg.dst_saddr.in = *((struct in_addr *)&conn->sic->dest_ip_xlate);
    1267                 } else {
     1305                } else
     1306#ifdef SFE_SUPPORT_IPV6
     1307                {
    12681308                        fc_msg.ethertype = AF_INET6;
    12691309                        fc_msg.src_saddr.in6 = *((struct in6_addr *)&conn->sic->src_ip);
    12701310                        fc_msg.dst_saddr.in6 = *((struct in6_addr *)&conn->sic->dest_ip_xlate);
    12711311                }
    1272 
     1312#endif
    12731313                fc_msg.proto = conn->sic->protocol;
    12741314                fc_msg.sport = conn->sic->src_port;
     
    13431383        tuple.dst.u.all = (__be16)sis->dest_port;
    13441384
     1385#ifdef SFE_SUPPORT_IPV6
    13451386        if (sis->is_v6) {
    13461387                tuple.src.u3.in6 = *((struct in6_addr *)sis->src_ip.ip6);
     
    13521393                            &tuple.src.u3.in6, (unsigned int)ntohs(tuple.src.u.all),
    13531394                            &tuple.dst.u3.in6, (unsigned int)ntohs(tuple.dst.u.all));
    1354         } else {
     1395        } else
     1396#endif
     1397        {
    13551398                tuple.src.u3.ip = sis->src_ip.ip;
    13561399                tuple.dst.u3.ip = sis->dest_ip.ip;
     
    14131456        if (acct) {
    14141457                spin_lock_bh(&ct->lock);
    1415                 atomic64_set(&SFE_ACCT_COUNTER(acct)[IP_CT_DIR_ORIGINAL].packets, sis->src_packet_count);
    1416                 atomic64_set(&SFE_ACCT_COUNTER(acct)[IP_CT_DIR_ORIGINAL].bytes, sis->src_byte_count);
    1417                 atomic64_set(&SFE_ACCT_COUNTER(acct)[IP_CT_DIR_REPLY].packets, sis->dest_packet_count);
    1418                 atomic64_set(&SFE_ACCT_COUNTER(acct)[IP_CT_DIR_REPLY].bytes, sis->dest_byte_count);
     1458                atomic64_add(sis->src_new_packet_count, &SFE_ACCT_COUNTER(acct)[IP_CT_DIR_ORIGINAL].packets);
     1459                atomic64_add(sis->src_new_byte_count, &SFE_ACCT_COUNTER(acct)[IP_CT_DIR_ORIGINAL].bytes);
     1460                atomic64_add(sis->dest_new_packet_count, &SFE_ACCT_COUNTER(acct)[IP_CT_DIR_REPLY].packets);
     1461                atomic64_add(sis->dest_new_byte_count, &SFE_ACCT_COUNTER(acct)[IP_CT_DIR_REPLY].bytes);
    14191462                spin_unlock_bh(&ct->lock);
    14201463        }
     
    14641507#endif
    14651508        }
     1509
    14661510        return NOTIFY_DONE;
    14671511}
     
    14771521                sfe_ipv4_destroy_all_rules_for_dev(dev);
    14781522        }
     1523
    14791524        return NOTIFY_DONE;
    14801525}
    14811526
     1527#ifdef SFE_SUPPORT_IPV6
    14821528/*
    14831529 * fast_classifier_inet6_event()
     
    14901536                sfe_ipv6_destroy_all_rules_for_dev(dev);
    14911537        }
     1538
    14921539        return NOTIFY_DONE;
    14931540}
    1494 
    1495 
     1541#endif
    14961542/*
    14971543 * fast_classifier_get_offload_at_pkts()
     
    15331579        struct sfe_connection *conn;
    15341580        u32 i;
     1581#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0))
     1582        struct hlist_node *node;
     1583#endif
    15351584
    15361585        spin_lock_bh(&sfe_connections_lock);
     
    15441593                        atomic_read(&offloaded_fail_msgs),
    15451594                        atomic_read(&done_fail_msgs));
    1546         sfe_hash_for_each(fc_conn_ht, i, conn, hl) {
     1595        sfe_hash_for_each(fc_conn_ht, i, node, conn, hl) {
    15471596                len += scnprintf(buf + len, PAGE_SIZE - len,
    15481597                                (conn->is_v4 ? "o=%d, p=%d [%pM]:%pI4:%u %pI4:%u:[%pM] m=%08x h=%d\n" : "o=%d, p=%d [%pM]:%pI6:%u %pI6:%u:[%pM] m=%08x h=%d\n"),
     
    16171666 * sysfs attributes.
    16181667 */
    1619 static const struct device_attribute fast_classifier_attrs[] = {
    1620         __ATTR(offload_at_pkts, S_IWUSR | S_IRUGO, fast_classifier_get_offload_at_pkts, fast_classifier_set_offload_at_pkts),
    1621         __ATTR(debug_info, S_IRUGO, fast_classifier_get_debug_info, NULL),
    1622         __ATTR(skip_to_bridge_ingress, S_IWUSR | S_IRUGO, fast_classifier_get_skip_bridge_ingress, fast_classifier_set_skip_bridge_ingress),
    1623         __ATTR(exceptions, S_IRUGO, fast_classifier_get_exceptions, NULL),
    1624 };
     1668static const struct device_attribute fast_classifier_offload_at_pkts_attr =
     1669        __ATTR(offload_at_pkts, S_IWUSR | S_IRUGO, fast_classifier_get_offload_at_pkts, fast_classifier_set_offload_at_pkts);
     1670static const struct device_attribute fast_classifier_debug_info_attr =
     1671        __ATTR(debug_info, S_IRUGO, fast_classifier_get_debug_info, NULL);
     1672static const struct device_attribute fast_classifier_skip_bridge_ingress =
     1673        __ATTR(skip_to_bridge_ingress, S_IWUSR | S_IRUGO, fast_classifier_get_skip_bridge_ingress, fast_classifier_set_skip_bridge_ingress);
     1674static const struct device_attribute fast_classifier_exceptions_attr =
     1675        __ATTR(exceptions, S_IRUGO, fast_classifier_get_exceptions, NULL);
    16251676
    16261677/*
     
    16311682        struct fast_classifier *sc = &__fsc;
    16321683        int result = -1;
    1633         size_t i, j;
    16341684
    16351685        printk(KERN_ALERT "fast-classifier: starting up\n");
     
    16471697        }
    16481698
    1649         for (i = 0; i < ARRAY_SIZE(fast_classifier_attrs); i++) {
    1650                 result = sysfs_create_file(sc->sys_fast_classifier, &fast_classifier_attrs[i].attr);
    1651                 if (result) {
    1652                         DEBUG_ERROR("failed to register %s : %d\n",
    1653                                     fast_classifier_attrs[i].attr.name, result);
    1654                         goto exit2;
    1655                 }
     1699        result = sysfs_create_file(sc->sys_fast_classifier, &fast_classifier_offload_at_pkts_attr.attr);
     1700        if (result) {
     1701                DEBUG_ERROR("failed to register offload at pkgs: %d\n", result);
     1702                goto exit2;
     1703        }
     1704
     1705        result = sysfs_create_file(sc->sys_fast_classifier, &fast_classifier_debug_info_attr.attr);
     1706        if (result) {
     1707                DEBUG_ERROR("failed to register debug dev: %d\n", result);
     1708                sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_offload_at_pkts_attr.attr);
     1709                goto exit2;
     1710        }
     1711
     1712        result = sysfs_create_file(sc->sys_fast_classifier, &fast_classifier_skip_bridge_ingress.attr);
     1713        if (result) {
     1714                DEBUG_ERROR("failed to register skip bridge on ingress: %d\n", result);
     1715                sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_offload_at_pkts_attr.attr);
     1716                sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_debug_info_attr.attr);
     1717                goto exit2;
     1718        }
     1719
     1720        result = sysfs_create_file(sc->sys_fast_classifier, &fast_classifier_exceptions_attr.attr);
     1721        if (result) {
     1722                DEBUG_ERROR("failed to register exceptions file: %d\n", result);
     1723                sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_offload_at_pkts_attr.attr);
     1724                sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_debug_info_attr.attr);
     1725                sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_skip_bridge_ingress.attr);
     1726                goto exit2;
    16561727        }
    16571728
     
    17581829#endif
    17591830        unregister_netdevice_notifier(&sc->dev_notifier);
     1831        sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_offload_at_pkts_attr.attr);
     1832        sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_debug_info_attr.attr);
     1833        sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_skip_bridge_ingress.attr);
     1834        sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_exceptions_attr.attr);
    17601835
    17611836exit2:
    1762         for (j = 0; j < i; j++) {
    1763                 sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_attrs[j].attr);
    1764         }
    17651837        kobject_put(sc->sys_fast_classifier);
    17661838
     
    18051877        sfe_ipv6_destroy_all_rules_for_dev(NULL);
    18061878#endif
    1807 
    18081879
    18091880#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0))
     
    18341905        kobject_put(sc->sys_fast_classifier);
    18351906}
    1836 
  • src/linux/universal/linux-3.18/net/shortcut-fe/sfe_backport.h

    r32708 r32717  
    134134#endif
    135135
    136 #define sfe_hash_for_each_possible(name, obj, member, key) \
     136#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
     137#define sfe_hash_for_each_possible(name, obj, node, member, key) \
    137138        hash_for_each_possible(name, obj, member, key)
     139#else
     140#define sfe_hash_for_each_possible(name, obj, node, member, key) \
     141        hash_for_each_possible(name, obj, node, member, key)
     142#endif
    138143
    139 #define sfe_hash_for_each(name, bkt, obj, member) \
     144#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
     145#define sfe_hash_for_each(name, bkt, node, obj, member) \
    140146        hash_for_each(name, bkt, obj, member)
     147#else
     148#define sfe_hash_for_each(name, bkt, node, obj, member) \
     149        hash_for_each(name, bkt, node, obj, member)
     150#endif
     151
     152#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
     153#define sfe_dst_get_neighbour(dst, daddr) dst_neigh_lookup(dst, addr)
     154#else
     155static inline struct neighbour *
     156sfe_dst_get_neighbour(struct dst_entry *dst, void *daddr)
     157{
     158        struct neighbour *neigh = dst_get_neighbour_noref(dst);
     159
     160        if (neigh)
     161                neigh_hold(neigh);
     162
     163        return neigh;
     164}
     165#endif
     166
    141167
    142168#endif
  • src/linux/universal/linux-3.2/net/shortcut-fe/fast-classifier.c

    r32716 r32717  
    44 *      fast-classifier
    55 *
    6  * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
     6 * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved.
    77 * Permission to use, copy, modify, and/or distribute this software for
    88 * any purpose with or without fee is hereby granted, provided that the
     
    257257                ret = sfe_ipv4_recv(dev, skb);
    258258
    259         } 
     259        }
    260260#ifdef SFE_SUPPORT_IPV6
    261 
    262261        else if (likely(htons(ETH_P_IPV6) == skb->protocol)) {
    263262                struct inet6_dev *in_dev;
     
    283282                ret = sfe_ipv6_recv(dev, skb);
    284283
    285         } 
     284        }
    286285#endif
    287286        else {
     
    380379}
    381380
    382 
    383381static DEFINE_SPINLOCK(sfe_connections_lock);
    384382
     
    388386        struct nf_conn *ct;
    389387        int hits;
     388        int offload_permit;
    390389        int offloaded;
    391390        bool is_v4;
     
    471470        struct sk_buff *skb;
    472471        int rc;
     472        int buf_len;
     473        int total_len;
    473474        void *msg_head;
    474475
    475         skb = genlmsg_new(sizeof(*fc_msg) + fast_classifier_gnl_family.hdrsize,
    476                           GFP_ATOMIC);
     476        /*
     477         * Calculate our packet payload size.
     478         * Start with our family header.
     479         */
     480        buf_len = fast_classifier_gnl_family.hdrsize;
     481
     482        /*
     483         * Add the nla_total_size of each attribute we're going to nla_put().
     484         */
     485        buf_len += nla_total_size(sizeof(*fc_msg));
     486
     487        /*
     488         * Lastly we need to add space for the NL message header since
     489         * genlmsg_new only accounts for the GENL header and not the
     490         * outer NL header. To do this, we use a NL helper function which
     491         * calculates the total size of a netlink message given a payload size.
     492         * Note this value does not include the GENL header, but that's
     493         * added automatically by genlmsg_new.
     494         */
     495        total_len = nlmsg_total_size(buf_len);
     496        skb = genlmsg_new(total_len, GFP_ATOMIC);
    477497        if (!skb)
    478498                return;
     
    491511        }
    492512
    493         genlmsg_end(skb, msg_head);
     513#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 19 , 0))
     514        rc = genlmsg_end(skb, msg_head);
    494515        if (rc < 0) {
    495516                genlmsg_cancel(skb, msg_head);
     
    497518                return;
    498519        }
     520#else
     521        genlmsg_end(skb, msg_head);
     522
     523#endif
    499524
    500525#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
     
    524549
    525550        DEBUG_TRACE("Notify NL message %d ", msg);
    526         DEBUG_TRACE("sip=%pIS dip=%pIS ", &fc_msg->src_saddr, &fc_msg->dst_saddr);
     551        if (fc_msg->ethertype == AF_INET) {
     552                DEBUG_TRACE("sip=%pI4 dip=%pI4 ", &fc_msg->src_saddr, &fc_msg->dst_saddr);
     553        } else {
     554                DEBUG_TRACE("sip=%pI6 dip=%pI6 ", &fc_msg->src_saddr, &fc_msg->dst_saddr);
     555        }
    527556        DEBUG_TRACE("protocol=%d sport=%d dport=%d smac=%pM dmac=%pM\n",
    528557                    fc_msg->proto, fc_msg->sport, fc_msg->dport, fc_msg->smac, fc_msg->dmac);
     
    541570        struct sfe_connection_create *p_sic;
    542571        struct sfe_connection *conn;
    543         struct hlist_node *h;
    544572        u32 key;
     573#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0))
     574        struct hlist_node *node;
     575#endif
    545576
    546577        key = fc_conn_hash(saddr, daddr, sport, dport, is_v4);
    547578
    548         sfe_hash_for_each_possible(h, fc_conn_ht, conn, hl, key) {
     579        sfe_hash_for_each_possible(fc_conn_ht, conn, node, hl, key) {
    549580                if (conn->is_v4 != is_v4) {
    550581                        continue;
     
    579610        struct sfe_connection_create *p_sic;
    580611        struct sfe_connection *conn;
    581         struct hlist_node *h;
    582         struct hlist_node *h2;
    583612        u32 key;
     613#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0))
     614        struct hlist_node *node;
     615#endif
    584616
    585617        key = fc_conn_hash(saddr, daddr, sport, dport, is_v4);
    586618
    587         sfe_hash_for_each_possible(h, fc_conn_ht, conn, hl, key) {
     619        sfe_hash_for_each_possible(fc_conn_ht, conn, node, hl, key) {
    588620                if (conn->is_v4 != is_v4) {
    589621                        continue;
     
    606638        key = fc_conn_hash(daddr, saddr, dport, sport, is_v4);
    607639
    608         sfe_hash_for_each_possible(h2, fc_conn_ht, conn, hl, key) {
     640        sfe_hash_for_each_possible(fc_conn_ht, conn, node, hl, key) {
    609641                if (conn->is_v4 != is_v4) {
    610642                        continue;
     
    654686        DEBUG_TRACE(" -> adding item to sfe_connections, new size: %d\n", sfe_connections_size);
    655687
    656         DEBUG_TRACE("new offloadable: key: %u proto: %d src_ip: %pIS dst_ip: %pIS, src_port: %d, dst_port: %d\n",
    657                 key, sic->protocol, &(sic->src_ip), &(sic->dest_ip), sic->src_port, sic->dest_port);
     688        if (conn->is_v4) {
     689                DEBUG_TRACE("new offloadable: key: %u proto: %d src_ip: %pI4 dst_ip: %pI4, src_port: %d, dst_port: %d\n",
     690                                key, sic->protocol, &(sic->src_ip), &(sic->dest_ip), sic->src_port, sic->dest_port);
     691        } else {
     692                DEBUG_TRACE("new offloadable: key: %u proto: %d src_ip: %pI6 dst_ip: %pI6, src_port: %d, dst_port: %d\n",
     693                                key, sic->protocol, &(sic->src_ip), &(sic->dest_ip), sic->src_port, sic->dest_port);
     694        }
    658695
    659696        return conn;
     
    667704fast_classifier_offload_genl_msg(struct sk_buff *skb, struct genl_info *info)
    668705{
    669         int ret;
    670706        struct nlattr *na;
    671707        struct fast_classifier_tuple *fc_msg;
     
    675711        fc_msg = nla_data(na);
    676712
    677         DEBUG_TRACE("want to offload: %d-%d, %pIS, %pIS, %d, %d SMAC=%pM DMAC=%pM\n" :
    678                 fc_msg->ethertype,
    679                 fc_msg->proto,
    680                 &fc_msg->src_saddr,
    681                 &fc_msg->dst_saddr,
    682                 fc_msg->sport,
    683                 fc_msg->dport,
    684                 fc_msg->smac,
    685                 fc_msg->dmac);
     713        DEBUG_TRACE((fc_msg->ethertype == AF_INET ?
     714                "want to offload: %d-%d, %pI4, %pI4, %d, %d SMAC=%pM DMAC=%pM\n" :
     715                "want to offload: %d-%d, %pI6, %pI6, %d, %d SMAC=%pM DMAC=%pM\n"),
     716                    fc_msg->ethertype,
     717                    fc_msg->proto,
     718                    &fc_msg->src_saddr,
     719                    &fc_msg->dst_saddr,
     720                    fc_msg->sport,
     721                    fc_msg->dport,
     722                    fc_msg->smac,
     723                    fc_msg->dmac);
    686724
    687725        spin_lock_bh(&sfe_connections_lock);
     
    699737        }
    700738
    701         if (conn->offloaded != 0) {
    702                 spin_unlock_bh(&sfe_connections_lock);
    703                 DEBUG_TRACE("GOT REQUEST TO OFFLOAD ALREADY OFFLOADED CONN FROM USERSPACE\n");
    704                 return 0;
    705         }
    706 
    707         DEBUG_TRACE("USERSPACE OFFLOAD REQUEST, MATCH FOUND, WILL OFFLOAD\n");
    708         if (fast_classifier_update_protocol(conn->sic, conn->ct) == 0) {
    709                 spin_unlock_bh(&sfe_connections_lock);
    710                 DEBUG_TRACE("UNKNOWN PROTOCOL OR CONNECTION CLOSING, SKIPPING\n");
    711                 return 0;
    712         }
     739        conn->offload_permit = 1;
     740        spin_unlock_bh(&sfe_connections_lock);
     741        atomic_inc(&offload_msgs);
    713742
    714743        DEBUG_TRACE("INFO: calling sfe rule creation!\n");
    715         spin_unlock_bh(&sfe_connections_lock);
    716         ret = conn->is_v4 ? sfe_ipv4_create_rule(conn->sic) : sfe_ipv6_create_rule(conn->sic);
    717         if ((ret == 0) || (ret == -EADDRINUSE)) {
    718                 conn->offloaded = 1;
    719                 fast_classifier_send_genl_msg(FAST_CLASSIFIER_C_OFFLOADED,
    720                                               fc_msg);
    721         }
    722 
    723         atomic_inc(&offload_msgs);
    724744        return 0;
    725745}
     
    840860         * Get addressing information, non-NAT first
    841861         */
    842         if (is_v4) {
     862        if (likely(is_v4)) {
    843863                u32 dscp;
    844864
     
    895915        }
    896916#endif
     917
    897918        switch (sic.protocol) {
    898919        case IPPROTO_TCP:
     
    940961        }
    941962
    942         DEBUG_TRACE("POST_ROUTE: checking new connection: %d src_ip: %pIS dst_ip: %pIS, src_port: %d, dst_port: %d\n",
    943                 sic.protocol, &sic.src_ip, &sic.dest_ip, sic.src_port, sic.dest_port);
     963        if (is_v4) {
     964                DEBUG_TRACE("POST_ROUTE: checking new connection: %d src_ip: %pI4 dst_ip: %pI4, src_port: %d, dst_port: %d\n",
     965                            sic.protocol, &sic.src_ip, &sic.dest_ip, sic.src_port, sic.dest_port);
     966        } else {
     967                DEBUG_TRACE("POST_ROUTE: checking new connection: %d src_ip: %pI6 dst_ip: %pI6, src_port: %d, dst_port: %d\n",
     968                            sic.protocol, &sic.src_ip, &sic.dest_ip, sic.src_port, sic.dest_port);
     969        }
    944970
    945971        /*
     
    954980
    955981                if (!conn->offloaded) {
    956                         if (conn->hits >= offload_at_pkts) {
     982                        if (conn->offload_permit || conn->hits >= offload_at_pkts) {
    957983                                DEBUG_TRACE("OFFLOADING CONNECTION, TOO MANY HITS\n");
    958984
     
    9751001                                                fc_msg.src_saddr.in = *((struct in_addr *)&sic.src_ip);
    9761002                                                fc_msg.dst_saddr.in = *((struct in_addr *)&sic.dest_ip_xlate);
    977                                         } else {
     1003                                        }
     1004#ifdef SFE_SUPPORT_IPV6
     1005                                        else {
    9781006                                                fc_msg.ethertype = AF_INET6;
    9791007                                                fc_msg.src_saddr.in6 = *((struct in6_addr *)&sic.src_ip);
    9801008                                                fc_msg.dst_saddr.in6 = *((struct in6_addr *)&sic.dest_ip_xlate);
    9811009                                        }
    982 
     1010#endif
    9831011                                        fc_msg.proto = sic.protocol;
    9841012                                        fc_msg.sport = sic.src_port;
     
    10771105        }
    10781106        conn->hits = 0;
     1107        conn->offload_permit = 0;
    10791108        conn->offloaded = 0;
    10801109        conn->is_v4 = is_v4;
     
    11301159
    11311160#ifdef SFE_SUPPORT_IPV6
     1161
    11321162/*
    11331163 * fast_classifier_ipv6_post_routing_hook()
     
    12091239                sid.dest_ip.ip6[0] = *((struct sfe_ipv6_addr *)&orig_tuple.dst.u3.in6);
    12101240                is_v4 = false;
    1211         } 
     1241        }
    12121242#endif
    12131243        else {
     
    12571287        }
    12581288
    1259         DEBUG_TRACE("Try to clean up: proto: %d src_ip: %pIS dst_ip: %pIS, src_port: %d, dst_port: %d\n",
    1260                 sid.protocol, &sid.src_ip, &sid.dest_ip, sid.src_port, sid.dest_port);
     1289        if (is_v4) {
     1290                DEBUG_TRACE("Try to clean up: proto: %d src_ip: %pI4 dst_ip: %pI4, src_port: %d, dst_port: %d\n",
     1291                            sid.protocol, &sid.src_ip, &sid.dest_ip, sid.src_port, sid.dest_port);
     1292        } else {
     1293                DEBUG_TRACE("Try to clean up: proto: %d src_ip: %pI6 dst_ip: %pI6, src_port: %d, dst_port: %d\n",
     1294                            sid.protocol, &sid.src_ip, &sid.dest_ip, sid.src_port, sid.dest_port);
     1295        }
    12611296
    12621297        spin_lock_bh(&sfe_connections_lock);
     
    12681303                        fc_msg.src_saddr.in = *((struct in_addr *)&conn->sic->src_ip);
    12691304                        fc_msg.dst_saddr.in = *((struct in_addr *)&conn->sic->dest_ip_xlate);
    1270                 } else {
     1305                } else
     1306#ifdef SFE_SUPPORT_IPV6
     1307                {
    12711308                        fc_msg.ethertype = AF_INET6;
    12721309                        fc_msg.src_saddr.in6 = *((struct in6_addr *)&conn->sic->src_ip);
    12731310                        fc_msg.dst_saddr.in6 = *((struct in6_addr *)&conn->sic->dest_ip_xlate);
    12741311                }
    1275 
     1312#endif
    12761313                fc_msg.proto = conn->sic->protocol;
    12771314                fc_msg.sport = conn->sic->src_port;
     
    13461383        tuple.dst.u.all = (__be16)sis->dest_port;
    13471384
     1385#ifdef SFE_SUPPORT_IPV6
    13481386        if (sis->is_v6) {
    13491387                tuple.src.u3.in6 = *((struct in6_addr *)sis->src_ip.ip6);
     
    13551393                            &tuple.src.u3.in6, (unsigned int)ntohs(tuple.src.u.all),
    13561394                            &tuple.dst.u3.in6, (unsigned int)ntohs(tuple.dst.u.all));
    1357         } else {
     1395        } else
     1396#endif
     1397        {
    13581398                tuple.src.u3.ip = sis->src_ip.ip;
    13591399                tuple.dst.u3.ip = sis->dest_ip.ip;
     
    14091449        if (!test_bit(IPS_FIXED_TIMEOUT_BIT, &ct->status)) {
    14101450                spin_lock_bh(&ct->lock);
    1411                 ct->timeout.expires += sis->delta_jiffies;
     1451                ct->timeout += sis->delta_jiffies;
    14121452                spin_unlock_bh(&ct->lock);
    14131453        }
     
    14161456        if (acct) {
    14171457                spin_lock_bh(&ct->lock);
    1418                 atomic64_set((atomic64_t *)&SFE_ACCT_COUNTER(acct)[IP_CT_DIR_ORIGINAL].packets, sis->src_packet_count);
    1419                 atomic64_set((atomic64_t *)&SFE_ACCT_COUNTER(acct)[IP_CT_DIR_ORIGINAL].bytes, sis->src_byte_count);
    1420                 atomic64_set((atomic64_t *)&SFE_ACCT_COUNTER(acct)[IP_CT_DIR_REPLY].packets, sis->dest_packet_count);
    1421                 atomic64_set((atomic64_t *)&SFE_ACCT_COUNTER(acct)[IP_CT_DIR_REPLY].bytes, sis->dest_byte_count);
     1458                atomic64_add(sis->src_new_packet_count, &SFE_ACCT_COUNTER(acct)[IP_CT_DIR_ORIGINAL].packets);
     1459                atomic64_add(sis->src_new_byte_count, &SFE_ACCT_COUNTER(acct)[IP_CT_DIR_ORIGINAL].bytes);
     1460                atomic64_add(sis->dest_new_packet_count, &SFE_ACCT_COUNTER(acct)[IP_CT_DIR_REPLY].packets);
     1461                atomic64_add(sis->dest_new_byte_count, &SFE_ACCT_COUNTER(acct)[IP_CT_DIR_REPLY].bytes);
    14221462                spin_unlock_bh(&ct->lock);
    14231463        }
     
    14671507#endif
    14681508        }
     1509
    14691510        return NOTIFY_DONE;
    14701511}
     
    14801521                sfe_ipv4_destroy_all_rules_for_dev(dev);
    14811522        }
     1523
    14821524        return NOTIFY_DONE;
    14831525}
    14841526
     1527#ifdef SFE_SUPPORT_IPV6
    14851528/*
    14861529 * fast_classifier_inet6_event()
     
    14931536                sfe_ipv6_destroy_all_rules_for_dev(dev);
    14941537        }
     1538
    14951539        return NOTIFY_DONE;
    14961540}
    1497 
    1498 
     1541#endif
    14991542/*
    15001543 * fast_classifier_get_offload_at_pkts()
     
    15361579        struct sfe_connection *conn;
    15371580        u32 i;
    1538         struct hlist_node *h;
     1581#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0))
     1582        struct hlist_node *node;
     1583#endif
    15391584
    15401585        spin_lock_bh(&sfe_connections_lock);
     
    15481593                        atomic_read(&offloaded_fail_msgs),
    15491594                        atomic_read(&done_fail_msgs));
    1550         sfe_hash_for_each(h, fc_conn_ht, i, conn, hl) {
     1595        sfe_hash_for_each(fc_conn_ht, i, node, conn, hl) {
    15511596                len += scnprintf(buf + len, PAGE_SIZE - len,
    15521597                                (conn->is_v4 ? "o=%d, p=%d [%pM]:%pI4:%u %pI4:%u:[%pM] m=%08x h=%d\n" : "o=%d, p=%d [%pM]:%pI6:%u %pI6:%u:[%pM] m=%08x h=%d\n"),
     
    16211666 * sysfs attributes.
    16221667 */
    1623 static const struct device_attribute fast_classifier_attrs[] = {
    1624         __ATTR(offload_at_pkts, S_IWUSR | S_IRUGO, fast_classifier_get_offload_at_pkts, fast_classifier_set_offload_at_pkts),
    1625         __ATTR(debug_info, S_IRUGO, fast_classifier_get_debug_info, NULL),
    1626         __ATTR(skip_to_bridge_ingress, S_IWUSR | S_IRUGO, fast_classifier_get_skip_bridge_ingress, fast_classifier_set_skip_bridge_ingress),
    1627         __ATTR(exceptions, S_IRUGO, fast_classifier_get_exceptions, NULL),
    1628 };
     1668static const struct device_attribute fast_classifier_offload_at_pkts_attr =
     1669        __ATTR(offload_at_pkts, S_IWUSR | S_IRUGO, fast_classifier_get_offload_at_pkts, fast_classifier_set_offload_at_pkts);
     1670static const struct device_attribute fast_classifier_debug_info_attr =
     1671        __ATTR(debug_info, S_IRUGO, fast_classifier_get_debug_info, NULL);
     1672static const struct device_attribute fast_classifier_skip_bridge_ingress =
     1673        __ATTR(skip_to_bridge_ingress, S_IWUSR | S_IRUGO, fast_classifier_get_skip_bridge_ingress, fast_classifier_set_skip_bridge_ingress);
     1674static const struct device_attribute fast_classifier_exceptions_attr =
     1675        __ATTR(exceptions, S_IRUGO, fast_classifier_get_exceptions, NULL);
    16291676
    16301677/*
     
    16351682        struct fast_classifier *sc = &__fsc;
    16361683        int result = -1;
    1637         size_t i, j;
    16381684
    16391685        printk(KERN_ALERT "fast-classifier: starting up\n");
     
    16511697        }
    16521698
    1653         for (i = 0; i < ARRAY_SIZE(fast_classifier_attrs); i++) {
    1654                 result = sysfs_create_file(sc->sys_fast_classifier, &fast_classifier_attrs[i].attr);
    1655                 if (result) {
    1656                         DEBUG_ERROR("failed to register %s : %d\n",
    1657                                     fast_classifier_attrs[i].attr.name, result);
    1658                         goto exit2;
    1659                 }
     1699        result = sysfs_create_file(sc->sys_fast_classifier, &fast_classifier_offload_at_pkts_attr.attr);
     1700        if (result) {
     1701                DEBUG_ERROR("failed to register offload at pkgs: %d\n", result);
     1702                goto exit2;
     1703        }
     1704
     1705        result = sysfs_create_file(sc->sys_fast_classifier, &fast_classifier_debug_info_attr.attr);
     1706        if (result) {
     1707                DEBUG_ERROR("failed to register debug dev: %d\n", result);
     1708                sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_offload_at_pkts_attr.attr);
     1709                goto exit2;
     1710        }
     1711
     1712        result = sysfs_create_file(sc->sys_fast_classifier, &fast_classifier_skip_bridge_ingress.attr);
     1713        if (result) {
     1714                DEBUG_ERROR("failed to register skip bridge on ingress: %d\n", result);
     1715                sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_offload_at_pkts_attr.attr);
     1716                sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_debug_info_attr.attr);
     1717                goto exit2;
     1718        }
     1719
     1720        result = sysfs_create_file(sc->sys_fast_classifier, &fast_classifier_exceptions_attr.attr);
     1721        if (result) {
     1722                DEBUG_ERROR("failed to register exceptions file: %d\n", result);
     1723                sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_offload_at_pkts_attr.attr);
     1724                sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_debug_info_attr.attr);
     1725                sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_skip_bridge_ingress.attr);
     1726                goto exit2;
    16601727        }
    16611728
     
    17621829#endif
    17631830        unregister_netdevice_notifier(&sc->dev_notifier);
     1831        sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_offload_at_pkts_attr.attr);
     1832        sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_debug_info_attr.attr);
     1833        sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_skip_bridge_ingress.attr);
     1834        sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_exceptions_attr.attr);
    17641835
    17651836exit2:
    1766         for (j = 0; j < i; j++) {
    1767                 sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_attrs[j].attr);
    1768         }
    17691837        kobject_put(sc->sys_fast_classifier);
    17701838
     
    18091877        sfe_ipv6_destroy_all_rules_for_dev(NULL);
    18101878#endif
    1811 
    18121879
    18131880#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0))
     
    18381905        kobject_put(sc->sys_fast_classifier);
    18391906}
    1840 
  • src/linux/universal/linux-3.2/net/shortcut-fe/sfe_backport.h

    r32708 r32717  
    134134#endif
    135135
    136 #define sfe_hash_for_each_possible(h, name, obj, member, key) \
    137         hash_for_each_possible(h, name, obj, member, key)
     136#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
     137#define sfe_hash_for_each_possible(name, obj, node, member, key) \
     138        hash_for_each_possible(name, obj, member, key)
     139#else
     140#define sfe_hash_for_each_possible(name, obj, node, member, key) \
     141        hash_for_each_possible(name, obj, node, member, key)
     142#endif
    138143
    139 #define sfe_hash_for_each(h, name, bkt, obj, member) \
    140         hash_for_each(h, name, bkt, obj, member)
     144#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
     145#define sfe_hash_for_each(name, bkt, node, obj, member) \
     146        hash_for_each(name, bkt, obj, member)
     147#else
     148#define sfe_hash_for_each(name, bkt, node, obj, member) \
     149        hash_for_each(name, bkt, node, obj, member)
     150#endif
     151
     152#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
     153#define sfe_dst_get_neighbour(dst, daddr) dst_neigh_lookup(dst, addr)
     154#else
     155static inline struct neighbour *
     156sfe_dst_get_neighbour(struct dst_entry *dst, void *daddr)
     157{
     158        struct neighbour *neigh = dst_get_neighbour_noref(dst);
     159
     160        if (neigh)
     161                neigh_hold(neigh);
     162
     163        return neigh;
     164}
     165#endif
     166
    141167
    142168#endif
  • src/linux/universal/linux-4.4/net/shortcut-fe/fast-classifier.c

    r32716 r32717  
    44 *      fast-classifier
    55 *
    6  * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
     6 * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved.
    77 * Permission to use, copy, modify, and/or distribute this software for
    88 * any purpose with or without fee is hereby granted, provided that the
     
    257257                ret = sfe_ipv4_recv(dev, skb);
    258258
    259         } 
     259        }
    260260#ifdef SFE_SUPPORT_IPV6
    261 
    262261        else if (likely(htons(ETH_P_IPV6) == skb->protocol)) {
    263262                struct inet6_dev *in_dev;
     
    283282                ret = sfe_ipv6_recv(dev, skb);
    284283
    285         } 
     284        }
    286285#endif
    287286        else {
     
    380379}
    381380
    382 
    383381static DEFINE_SPINLOCK(sfe_connections_lock);
    384382
     
    388386        struct nf_conn *ct;
    389387        int hits;
     388        int offload_permit;
    390389        int offloaded;
    391390        bool is_v4;
     
    471470        struct sk_buff *skb;
    472471        int rc;
     472        int buf_len;
     473        int total_len;
    473474        void *msg_head;
    474475
    475         skb = genlmsg_new(sizeof(*fc_msg) + fast_classifier_gnl_family.hdrsize,
    476                           GFP_ATOMIC);
     476        /*
     477         * Calculate our packet payload size.
     478         * Start with our family header.
     479         */
     480        buf_len = fast_classifier_gnl_family.hdrsize;
     481
     482        /*
     483         * Add the nla_total_size of each attribute we're going to nla_put().
     484         */
     485        buf_len += nla_total_size(sizeof(*fc_msg));
     486
     487        /*
     488         * Lastly we need to add space for the NL message header since
     489         * genlmsg_new only accounts for the GENL header and not the
     490         * outer NL header. To do this, we use a NL helper function which
     491         * calculates the total size of a netlink message given a payload size.
     492         * Note this value does not include the GENL header, but that's
     493         * added automatically by genlmsg_new.
     494         */
     495        total_len = nlmsg_total_size(buf_len);
     496        skb = genlmsg_new(total_len, GFP_ATOMIC);
    477497        if (!skb)
    478498                return;
     
    491511        }
    492512
    493         genlmsg_end(skb, msg_head);
     513#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 19 , 0))
     514        rc = genlmsg_end(skb, msg_head);
    494515        if (rc < 0) {
    495516                genlmsg_cancel(skb, msg_head);
     
    497518                return;
    498519        }
     520#else
     521        genlmsg_end(skb, msg_head);
     522
     523#endif
    499524
    500525#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
     
    524549
    525550        DEBUG_TRACE("Notify NL message %d ", msg);
    526         DEBUG_TRACE("sip=%pIS dip=%pIS ", &fc_msg->src_saddr, &fc_msg->dst_saddr);
     551        if (fc_msg->ethertype == AF_INET) {
     552                DEBUG_TRACE("sip=%pI4 dip=%pI4 ", &fc_msg->src_saddr, &fc_msg->dst_saddr);
     553        } else {
     554                DEBUG_TRACE("sip=%pI6 dip=%pI6 ", &fc_msg->src_saddr, &fc_msg->dst_saddr);
     555        }
    527556        DEBUG_TRACE("protocol=%d sport=%d dport=%d smac=%pM dmac=%pM\n",
    528557                    fc_msg->proto, fc_msg->sport, fc_msg->dport, fc_msg->smac, fc_msg->dmac);
     
    542571        struct sfe_connection *conn;
    543572        u32 key;
     573#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0))
     574        struct hlist_node *node;
     575#endif
    544576
    545577        key = fc_conn_hash(saddr, daddr, sport, dport, is_v4);
    546578
    547         sfe_hash_for_each_possible(fc_conn_ht, conn, hl, key) {
     579        sfe_hash_for_each_possible(fc_conn_ht, conn, node, hl, key) {
    548580                if (conn->is_v4 != is_v4) {
    549581                        continue;
     
    579611        struct sfe_connection *conn;
    580612        u32 key;
     613#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0))
     614        struct hlist_node *node;
     615#endif
    581616
    582617        key = fc_conn_hash(saddr, daddr, sport, dport, is_v4);
    583618
    584         sfe_hash_for_each_possible(fc_conn_ht, conn, hl, key) {
     619        sfe_hash_for_each_possible(fc_conn_ht, conn, node, hl, key) {
    585620                if (conn->is_v4 != is_v4) {
    586621                        continue;
     
    603638        key = fc_conn_hash(daddr, saddr, dport, sport, is_v4);
    604639
    605         sfe_hash_for_each_possible(fc_conn_ht, conn, hl, key) {
     640        sfe_hash_for_each_possible(fc_conn_ht, conn, node, hl, key) {
    606641                if (conn->is_v4 != is_v4) {
    607642                        continue;
     
    651686        DEBUG_TRACE(" -> adding item to sfe_connections, new size: %d\n", sfe_connections_size);
    652687
    653         DEBUG_TRACE("new offloadable: key: %u proto: %d src_ip: %pIS dst_ip: %pIS, src_port: %d, dst_port: %d\n",
    654                 key, sic->protocol, &(sic->src_ip), &(sic->dest_ip), sic->src_port, sic->dest_port);
     688        if (conn->is_v4) {
     689                DEBUG_TRACE("new offloadable: key: %u proto: %d src_ip: %pI4 dst_ip: %pI4, src_port: %d, dst_port: %d\n",
     690                                key, sic->protocol, &(sic->src_ip), &(sic->dest_ip), sic->src_port, sic->dest_port);
     691        } else {
     692                DEBUG_TRACE("new offloadable: key: %u proto: %d src_ip: %pI6 dst_ip: %pI6, src_port: %d, dst_port: %d\n",
     693                                key, sic->protocol, &(sic->src_ip), &(sic->dest_ip), sic->src_port, sic->dest_port);
     694        }
    655695
    656696        return conn;
     
    664704fast_classifier_offload_genl_msg(struct sk_buff *skb, struct genl_info *info)
    665705{
    666         int ret;
    667706        struct nlattr *na;
    668707        struct fast_classifier_tuple *fc_msg;
     
    672711        fc_msg = nla_data(na);
    673712
    674         DEBUG_TRACE("want to offload: %d-%d, %pIS, %pIS, %d, %d SMAC=%pM DMAC=%pM\n" :
    675                 fc_msg->ethertype,
    676                 fc_msg->proto,
    677                 &fc_msg->src_saddr,
    678                 &fc_msg->dst_saddr,
    679                 fc_msg->sport,
    680                 fc_msg->dport,
    681                 fc_msg->smac,
    682                 fc_msg->dmac);
     713        DEBUG_TRACE((fc_msg->ethertype == AF_INET ?
     714                "want to offload: %d-%d, %pI4, %pI4, %d, %d SMAC=%pM DMAC=%pM\n" :
     715                "want to offload: %d-%d, %pI6, %pI6, %d, %d SMAC=%pM DMAC=%pM\n"),
     716                    fc_msg->ethertype,
     717                    fc_msg->proto,
     718                    &fc_msg->src_saddr,
     719                    &fc_msg->dst_saddr,
     720                    fc_msg->sport,
     721                    fc_msg->dport,
     722                    fc_msg->smac,
     723                    fc_msg->dmac);
    683724
    684725        spin_lock_bh(&sfe_connections_lock);
     
    696737        }
    697738
    698         if (conn->offloaded != 0) {
    699                 spin_unlock_bh(&sfe_connections_lock);
    700                 DEBUG_TRACE("GOT REQUEST TO OFFLOAD ALREADY OFFLOADED CONN FROM USERSPACE\n");
    701                 return 0;
    702         }
    703 
    704         DEBUG_TRACE("USERSPACE OFFLOAD REQUEST, MATCH FOUND, WILL OFFLOAD\n");
    705         if (fast_classifier_update_protocol(conn->sic, conn->ct) == 0) {
    706                 spin_unlock_bh(&sfe_connections_lock);
    707                 DEBUG_TRACE("UNKNOWN PROTOCOL OR CONNECTION CLOSING, SKIPPING\n");
    708                 return 0;
    709         }
     739        conn->offload_permit = 1;
     740        spin_unlock_bh(&sfe_connections_lock);
     741        atomic_inc(&offload_msgs);
    710742
    711743        DEBUG_TRACE("INFO: calling sfe rule creation!\n");
    712         spin_unlock_bh(&sfe_connections_lock);
    713         ret = conn->is_v4 ? sfe_ipv4_create_rule(conn->sic) : sfe_ipv6_create_rule(conn->sic);
    714         if ((ret == 0) || (ret == -EADDRINUSE)) {
    715                 conn->offloaded = 1;
    716                 fast_classifier_send_genl_msg(FAST_CLASSIFIER_C_OFFLOADED,
    717                                               fc_msg);
    718         }
    719 
    720         atomic_inc(&offload_msgs);
    721744        return 0;
    722745}
     
    837860         * Get addressing information, non-NAT first
    838861         */
    839         if (is_v4) {
     862        if (likely(is_v4)) {
    840863                u32 dscp;
    841864
     
    892915        }
    893916#endif
     917
    894918        switch (sic.protocol) {
    895919        case IPPROTO_TCP:
     
    937961        }
    938962
    939         DEBUG_TRACE("POST_ROUTE: checking new connection: %d src_ip: %pIS dst_ip: %pIS, src_port: %d, dst_port: %d\n",
    940                 sic.protocol, &sic.src_ip, &sic.dest_ip, sic.src_port, sic.dest_port);
     963        if (is_v4) {
     964                DEBUG_TRACE("POST_ROUTE: checking new connection: %d src_ip: %pI4 dst_ip: %pI4, src_port: %d, dst_port: %d\n",
     965                            sic.protocol, &sic.src_ip, &sic.dest_ip, sic.src_port, sic.dest_port);
     966        } else {
     967                DEBUG_TRACE("POST_ROUTE: checking new connection: %d src_ip: %pI6 dst_ip: %pI6, src_port: %d, dst_port: %d\n",
     968                            sic.protocol, &sic.src_ip, &sic.dest_ip, sic.src_port, sic.dest_port);
     969        }
    941970
    942971        /*
     
    951980
    952981                if (!conn->offloaded) {
    953                         if (conn->hits >= offload_at_pkts) {
     982                        if (conn->offload_permit || conn->hits >= offload_at_pkts) {
    954983                                DEBUG_TRACE("OFFLOADING CONNECTION, TOO MANY HITS\n");
    955984
     
    9721001                                                fc_msg.src_saddr.in = *((struct in_addr *)&sic.src_ip);
    9731002                                                fc_msg.dst_saddr.in = *((struct in_addr *)&sic.dest_ip_xlate);
    974                                         } else {
     1003                                        }
     1004#ifdef SFE_SUPPORT_IPV6
     1005                                        else {
    9751006                                                fc_msg.ethertype = AF_INET6;
    9761007                                                fc_msg.src_saddr.in6 = *((struct in6_addr *)&sic.src_ip);
    9771008                                                fc_msg.dst_saddr.in6 = *((struct in6_addr *)&sic.dest_ip_xlate);
    9781009                                        }
    979 
     1010#endif
    9801011                                        fc_msg.proto = sic.protocol;
    9811012                                        fc_msg.sport = sic.src_port;
     
    10741105        }
    10751106        conn->hits = 0;
     1107        conn->offload_permit = 0;
    10761108        conn->offloaded = 0;
    10771109        conn->is_v4 = is_v4;
     
    11271159
    11281160#ifdef SFE_SUPPORT_IPV6
     1161
    11291162/*
    11301163 * fast_classifier_ipv6_post_routing_hook()
     
    12061239                sid.dest_ip.ip6[0] = *((struct sfe_ipv6_addr *)&orig_tuple.dst.u3.in6);
    12071240                is_v4 = false;
    1208         } 
     1241        }
    12091242#endif
    12101243        else {
     
    12541287        }
    12551288
    1256         DEBUG_TRACE("Try to clean up: proto: %d src_ip: %pIS dst_ip: %pIS, src_port: %d, dst_port: %d\n",
    1257                 sid.protocol, &sid.src_ip, &sid.dest_ip, sid.src_port, sid.dest_port);
     1289        if (is_v4) {
     1290                DEBUG_TRACE("Try to clean up: proto: %d src_ip: %pI4 dst_ip: %pI4, src_port: %d, dst_port: %d\n",
     1291                            sid.protocol, &sid.src_ip, &sid.dest_ip, sid.src_port, sid.dest_port);
     1292        } else {
     1293                DEBUG_TRACE("Try to clean up: proto: %d src_ip: %pI6 dst_ip: %pI6, src_port: %d, dst_port: %d\n",
     1294                            sid.protocol, &sid.src_ip, &sid.dest_ip, sid.src_port, sid.dest_port);
     1295        }
    12581296
    12591297        spin_lock_bh(&sfe_connections_lock);
     
    12651303                        fc_msg.src_saddr.in = *((struct in_addr *)&conn->sic->src_ip);
    12661304                        fc_msg.dst_saddr.in = *((struct in_addr *)&conn->sic->dest_ip_xlate);
    1267                 } else {
     1305                } else
     1306#ifdef SFE_SUPPORT_IPV6
     1307                {
    12681308                        fc_msg.ethertype = AF_INET6;
    12691309                        fc_msg.src_saddr.in6 = *((struct in6_addr *)&conn->sic->src_ip);
    12701310                        fc_msg.dst_saddr.in6 = *((struct in6_addr *)&conn->sic->dest_ip_xlate);
    12711311                }
    1272 
     1312#endif
    12731313                fc_msg.proto = conn->sic->protocol;
    12741314                fc_msg.sport = conn->sic->src_port;
     
    13431383        tuple.dst.u.all = (__be16)sis->dest_port;
    13441384
     1385#ifdef SFE_SUPPORT_IPV6
    13451386        if (sis->is_v6) {
    13461387                tuple.src.u3.in6 = *((struct in6_addr *)sis->src_ip.ip6);
     
    13521393                            &tuple.src.u3.in6, (unsigned int)ntohs(tuple.src.u.all),
    13531394                            &tuple.dst.u3.in6, (unsigned int)ntohs(tuple.dst.u.all));
    1354         } else {
     1395        } else
     1396#endif
     1397        {
    13551398                tuple.src.u3.ip = sis->src_ip.ip;
    13561399                tuple.dst.u3.ip = sis->dest_ip.ip;
     
    14131456        if (acct) {
    14141457                spin_lock_bh(&ct->lock);
    1415                 atomic64_set(&SFE_ACCT_COUNTER(acct)[IP_CT_DIR_ORIGINAL].packets, sis->src_packet_count);
    1416                 atomic64_set(&SFE_ACCT_COUNTER(acct)[IP_CT_DIR_ORIGINAL].bytes, sis->src_byte_count);
    1417                 atomic64_set(&SFE_ACCT_COUNTER(acct)[IP_CT_DIR_REPLY].packets, sis->dest_packet_count);
    1418                 atomic64_set(&SFE_ACCT_COUNTER(acct)[IP_CT_DIR_REPLY].bytes, sis->dest_byte_count);
     1458                atomic64_add(sis->src_new_packet_count, &SFE_ACCT_COUNTER(acct)[IP_CT_DIR_ORIGINAL].packets);
     1459                atomic64_add(sis->src_new_byte_count, &SFE_ACCT_COUNTER(acct)[IP_CT_DIR_ORIGINAL].bytes);
     1460                atomic64_add(sis->dest_new_packet_count, &SFE_ACCT_COUNTER(acct)[IP_CT_DIR_REPLY].packets);
     1461                atomic64_add(sis->dest_new_byte_count, &SFE_ACCT_COUNTER(acct)[IP_CT_DIR_REPLY].bytes);
    14191462                spin_unlock_bh(&ct->lock);
    14201463        }
     
    14641507#endif
    14651508        }
     1509
    14661510        return NOTIFY_DONE;
    14671511}
     
    14771521                sfe_ipv4_destroy_all_rules_for_dev(dev);
    14781522        }
     1523
    14791524        return NOTIFY_DONE;
    14801525}
    14811526
     1527#ifdef SFE_SUPPORT_IPV6
    14821528/*
    14831529 * fast_classifier_inet6_event()
     
    14901536                sfe_ipv6_destroy_all_rules_for_dev(dev);
    14911537        }
     1538
    14921539        return NOTIFY_DONE;
    14931540}
    1494 
    1495 
     1541#endif
    14961542/*
    14971543 * fast_classifier_get_offload_at_pkts()
     
    15331579        struct sfe_connection *conn;
    15341580        u32 i;
     1581#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0))
     1582        struct hlist_node *node;
     1583#endif
    15351584
    15361585        spin_lock_bh(&sfe_connections_lock);
     
    15441593                        atomic_read(&offloaded_fail_msgs),
    15451594                        atomic_read(&done_fail_msgs));
    1546         sfe_hash_for_each(fc_conn_ht, i, conn, hl) {
     1595        sfe_hash_for_each(fc_conn_ht, i, node, conn, hl) {
    15471596                len += scnprintf(buf + len, PAGE_SIZE - len,
    15481597                                (conn->is_v4 ? "o=%d, p=%d [%pM]:%pI4:%u %pI4:%u:[%pM] m=%08x h=%d\n" : "o=%d, p=%d [%pM]:%pI6:%u %pI6:%u:[%pM] m=%08x h=%d\n"),
     
    16171666 * sysfs attributes.
    16181667 */
    1619 static const struct device_attribute fast_classifier_attrs[] = {
    1620         __ATTR(offload_at_pkts, S_IWUSR | S_IRUGO, fast_classifier_get_offload_at_pkts, fast_classifier_set_offload_at_pkts),
    1621         __ATTR(debug_info, S_IRUGO, fast_classifier_get_debug_info, NULL),
    1622         __ATTR(skip_to_bridge_ingress, S_IWUSR | S_IRUGO, fast_classifier_get_skip_bridge_ingress, fast_classifier_set_skip_bridge_ingress),
    1623         __ATTR(exceptions, S_IRUGO, fast_classifier_get_exceptions, NULL),
    1624 };
     1668static const struct device_attribute fast_classifier_offload_at_pkts_attr =
     1669        __ATTR(offload_at_pkts, S_IWUSR | S_IRUGO, fast_classifier_get_offload_at_pkts, fast_classifier_set_offload_at_pkts);
     1670static const struct device_attribute fast_classifier_debug_info_attr =
     1671        __ATTR(debug_info, S_IRUGO, fast_classifier_get_debug_info, NULL);
     1672static const struct device_attribute fast_classifier_skip_bridge_ingress =
     1673        __ATTR(skip_to_bridge_ingress, S_IWUSR | S_IRUGO, fast_classifier_get_skip_bridge_ingress, fast_classifier_set_skip_bridge_ingress);
     1674static const struct device_attribute fast_classifier_exceptions_attr =
     1675        __ATTR(exceptions, S_IRUGO, fast_classifier_get_exceptions, NULL);
    16251676
    16261677/*
     
    16311682        struct fast_classifier *sc = &__fsc;
    16321683        int result = -1;
    1633         size_t i, j;
    16341684
    16351685        printk(KERN_ALERT "fast-classifier: starting up\n");
     
    16471697        }
    16481698
    1649         for (i = 0; i < ARRAY_SIZE(fast_classifier_attrs); i++) {
    1650                 result = sysfs_create_file(sc->sys_fast_classifier, &fast_classifier_attrs[i].attr);
    1651                 if (result) {
    1652                         DEBUG_ERROR("failed to register %s : %d\n",
    1653                                     fast_classifier_attrs[i].attr.name, result);
    1654                         goto exit2;
    1655                 }
     1699        result = sysfs_create_file(sc->sys_fast_classifier, &fast_classifier_offload_at_pkts_attr.attr);
     1700        if (result) {
     1701                DEBUG_ERROR("failed to register offload at pkgs: %d\n", result);
     1702                goto exit2;
     1703        }
     1704
     1705        result = sysfs_create_file(sc->sys_fast_classifier, &fast_classifier_debug_info_attr.attr);
     1706        if (result) {
     1707                DEBUG_ERROR("failed to register debug dev: %d\n", result);
     1708                sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_offload_at_pkts_attr.attr);
     1709                goto exit2;
     1710        }
     1711
     1712        result = sysfs_create_file(sc->sys_fast_classifier, &fast_classifier_skip_bridge_ingress.attr);
     1713        if (result) {
     1714                DEBUG_ERROR("failed to register skip bridge on ingress: %d\n", result);
     1715                sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_offload_at_pkts_attr.attr);
     1716                sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_debug_info_attr.attr);
     1717                goto exit2;
     1718        }
     1719
     1720        result = sysfs_create_file(sc->sys_fast_classifier, &fast_classifier_exceptions_attr.attr);
     1721        if (result) {
     1722                DEBUG_ERROR("failed to register exceptions file: %d\n", result);
     1723                sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_offload_at_pkts_attr.attr);
     1724                sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_debug_info_attr.attr);
     1725                sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_skip_bridge_ingress.attr);
     1726                goto exit2;
    16561727        }
    16571728
     
    17581829#endif
    17591830        unregister_netdevice_notifier(&sc->dev_notifier);
     1831        sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_offload_at_pkts_attr.attr);
     1832        sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_debug_info_attr.attr);
     1833        sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_skip_bridge_ingress.attr);
     1834        sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_exceptions_attr.attr);
    17601835
    17611836exit2:
    1762         for (j = 0; j < i; j++) {
    1763                 sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_attrs[j].attr);
    1764         }
    17651837        kobject_put(sc->sys_fast_classifier);
    17661838
     
    18051877        sfe_ipv6_destroy_all_rules_for_dev(NULL);
    18061878#endif
    1807 
    18081879
    18091880#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0))
     
    18341905        kobject_put(sc->sys_fast_classifier);
    18351906}
    1836 
  • src/linux/universal/linux-4.4/net/shortcut-fe/sfe_backport.h

    r32708 r32717  
    134134#endif
    135135
    136 #define sfe_hash_for_each_possible(name, obj, member, key) \
     136#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
     137#define sfe_hash_for_each_possible(name, obj, node, member, key) \
    137138        hash_for_each_possible(name, obj, member, key)
     139#else
     140#define sfe_hash_for_each_possible(name, obj, node, member, key) \
     141        hash_for_each_possible(name, obj, node, member, key)
     142#endif
    138143
    139 #define sfe_hash_for_each(name, bkt, obj, member) \
     144#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
     145#define sfe_hash_for_each(name, bkt, node, obj, member) \
    140146        hash_for_each(name, bkt, obj, member)
     147#else
     148#define sfe_hash_for_each(name, bkt, node, obj, member) \
     149        hash_for_each(name, bkt, node, obj, member)
     150#endif
     151
     152#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
     153#define sfe_dst_get_neighbour(dst, daddr) dst_neigh_lookup(dst, addr)
     154#else
     155static inline struct neighbour *
     156sfe_dst_get_neighbour(struct dst_entry *dst, void *daddr)
     157{
     158        struct neighbour *neigh = dst_get_neighbour_noref(dst);
     159
     160        if (neigh)
     161                neigh_hold(neigh);
     162
     163        return neigh;
     164}
     165#endif
     166
    141167
    142168#endif
  • src/linux/universal/linux-4.9/net/shortcut-fe/fast-classifier.c

    r32716 r32717  
    44 *      fast-classifier
    55 *
    6  * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved.
     6 * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved.
    77 * Permission to use, copy, modify, and/or distribute this software for
    88 * any purpose with or without fee is hereby granted, provided that the
     
    257257                ret = sfe_ipv4_recv(dev, skb);
    258258
    259         } 
     259        }
    260260#ifdef SFE_SUPPORT_IPV6
    261 
    262261        else if (likely(htons(ETH_P_IPV6) == skb->protocol)) {
    263262                struct inet6_dev *in_dev;
     
    283282                ret = sfe_ipv6_recv(dev, skb);
    284283
    285         } 
     284        }
    286285#endif
    287286        else {
     
    380379}
    381380
    382 
    383381static DEFINE_SPINLOCK(sfe_connections_lock);
    384382
     
    388386        struct nf_conn *ct;
    389387        int hits;
     388        int offload_permit;
    390389        int offloaded;
    391390        bool is_v4;
     
    471470        struct sk_buff *skb;
    472471        int rc;
     472        int buf_len;
     473        int total_len;
    473474        void *msg_head;
    474475
    475         skb = genlmsg_new(sizeof(*fc_msg) + fast_classifier_gnl_family.hdrsize,
    476                           GFP_ATOMIC);
     476        /*
     477         * Calculate our packet payload size.
     478         * Start with our family header.
     479         */
     480        buf_len = fast_classifier_gnl_family.hdrsize;
     481
     482        /*
     483         * Add the nla_total_size of each attribute we're going to nla_put().
     484         */
     485        buf_len += nla_total_size(sizeof(*fc_msg));
     486
     487        /*
     488         * Lastly we need to add space for the NL message header since
     489         * genlmsg_new only accounts for the GENL header and not the
     490         * outer NL header. To do this, we use a NL helper function which
     491         * calculates the total size of a netlink message given a payload size.
     492         * Note this value does not include the GENL header, but that's
     493         * added automatically by genlmsg_new.
     494         */
     495        total_len = nlmsg_total_size(buf_len);
     496        skb = genlmsg_new(total_len, GFP_ATOMIC);
    477497        if (!skb)
    478498                return;
     
    491511        }
    492512
    493         genlmsg_end(skb, msg_head);
     513#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 19 , 0))
     514        rc = genlmsg_end(skb, msg_head);
    494515        if (rc < 0) {
    495516                genlmsg_cancel(skb, msg_head);
     
    497518                return;
    498519        }
     520#else
     521        genlmsg_end(skb, msg_head);
     522
     523#endif
    499524
    500525#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
     
    524549
    525550        DEBUG_TRACE("Notify NL message %d ", msg);
    526         DEBUG_TRACE("sip=%pIS dip=%pIS ", &fc_msg->src_saddr, &fc_msg->dst_saddr);
     551        if (fc_msg->ethertype == AF_INET) {
     552                DEBUG_TRACE("sip=%pI4 dip=%pI4 ", &fc_msg->src_saddr, &fc_msg->dst_saddr);
     553        } else {
     554                DEBUG_TRACE("sip=%pI6 dip=%pI6 ", &fc_msg->src_saddr, &fc_msg->dst_saddr);
     555        }
    527556        DEBUG_TRACE("protocol=%d sport=%d dport=%d smac=%pM dmac=%pM\n",
    528557                    fc_msg->proto, fc_msg->sport, fc_msg->dport, fc_msg->smac, fc_msg->dmac);
     
    542571        struct sfe_connection *conn;
    543572        u32 key;
     573#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0))
     574        struct hlist_node *node;
     575#endif
    544576
    545577        key = fc_conn_hash(saddr, daddr, sport, dport, is_v4);
    546578
    547         sfe_hash_for_each_possible(fc_conn_ht, conn, hl, key) {
     579        sfe_hash_for_each_possible(fc_conn_ht, conn, node, hl, key) {
    548580                if (conn->is_v4 != is_v4) {
    549581                        continue;
     
    579611        struct sfe_connection *conn;
    580612        u32 key;
     613#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0))
     614        struct hlist_node *node;
     615#endif
    581616
    582617        key = fc_conn_hash(saddr, daddr, sport, dport, is_v4);
    583618
    584         sfe_hash_for_each_possible(fc_conn_ht, conn, hl, key) {
     619        sfe_hash_for_each_possible(fc_conn_ht, conn, node, hl, key) {
    585620                if (conn->is_v4 != is_v4) {
    586621                        continue;
     
    603638        key = fc_conn_hash(daddr, saddr, dport, sport, is_v4);
    604639
    605         sfe_hash_for_each_possible(fc_conn_ht, conn, hl, key) {
     640        sfe_hash_for_each_possible(fc_conn_ht, conn, node, hl, key) {
    606641                if (conn->is_v4 != is_v4) {
    607642                        continue;
     
    651686        DEBUG_TRACE(" -> adding item to sfe_connections, new size: %d\n", sfe_connections_size);
    652687
    653         DEBUG_TRACE("new offloadable: key: %u proto: %d src_ip: %pIS dst_ip: %pIS, src_port: %d, dst_port: %d\n",
    654                 key, sic->protocol, &(sic->src_ip), &(sic->dest_ip), sic->src_port, sic->dest_port);
     688        if (conn->is_v4) {
     689                DEBUG_TRACE("new offloadable: key: %u proto: %d src_ip: %pI4 dst_ip: %pI4, src_port: %d, dst_port: %d\n",
     690                                key, sic->protocol, &(sic->src_ip), &(sic->dest_ip), sic->src_port, sic->dest_port);
     691        } else {
     692                DEBUG_TRACE("new offloadable: key: %u proto: %d src_ip: %pI6 dst_ip: %pI6, src_port: %d, dst_port: %d\n",
     693                                key, sic->protocol, &(sic->src_ip), &(sic->dest_ip), sic->src_port, sic->dest_port);
     694        }
    655695
    656696        return conn;
     
    664704fast_classifier_offload_genl_msg(struct sk_buff *skb, struct genl_info *info)
    665705{
    666         int ret;
    667706        struct nlattr *na;
    668707        struct fast_classifier_tuple *fc_msg;
     
    672711        fc_msg = nla_data(na);
    673712
    674         DEBUG_TRACE("want to offload: %d-%d, %pIS, %pIS, %d, %d SMAC=%pM DMAC=%pM\n" :
    675                 fc_msg->ethertype,
    676                 fc_msg->proto,
    677                 &fc_msg->src_saddr,
    678                 &fc_msg->dst_saddr,
    679                 fc_msg->sport,
    680                 fc_msg->dport,
    681                 fc_msg->smac,
    682                 fc_msg->dmac);
     713        DEBUG_TRACE((fc_msg->ethertype == AF_INET ?
     714                "want to offload: %d-%d, %pI4, %pI4, %d, %d SMAC=%pM DMAC=%pM\n" :
     715                "want to offload: %d-%d, %pI6, %pI6, %d, %d SMAC=%pM DMAC=%pM\n"),
     716                    fc_msg->ethertype,
     717                    fc_msg->proto,
     718                    &fc_msg->src_saddr,
     719                    &fc_msg->dst_saddr,
     720                    fc_msg->sport,
     721                    fc_msg->dport,
     722                    fc_msg->smac,
     723                    fc_msg->dmac);
    683724
    684725        spin_lock_bh(&sfe_connections_lock);
     
    696737        }
    697738
    698         if (conn->offloaded != 0) {
    699                 spin_unlock_bh(&sfe_connections_lock);
    700                 DEBUG_TRACE("GOT REQUEST TO OFFLOAD ALREADY OFFLOADED CONN FROM USERSPACE\n");
    701                 return 0;
    702         }
    703 
    704         DEBUG_TRACE("USERSPACE OFFLOAD REQUEST, MATCH FOUND, WILL OFFLOAD\n");
    705         if (fast_classifier_update_protocol(conn->sic, conn->ct) == 0) {
    706                 spin_unlock_bh(&sfe_connections_lock);
    707                 DEBUG_TRACE("UNKNOWN PROTOCOL OR CONNECTION CLOSING, SKIPPING\n");
    708                 return 0;
    709         }
     739        conn->offload_permit = 1;
     740        spin_unlock_bh(&sfe_connections_lock);
     741        atomic_inc(&offload_msgs);
    710742
    711743        DEBUG_TRACE("INFO: calling sfe rule creation!\n");
    712         spin_unlock_bh(&sfe_connections_lock);
    713         ret = conn->is_v4 ? sfe_ipv4_create_rule(conn->sic) : sfe_ipv6_create_rule(conn->sic);
    714         if ((ret == 0) || (ret == -EADDRINUSE)) {
    715                 conn->offloaded = 1;
    716                 fast_classifier_send_genl_msg(FAST_CLASSIFIER_C_OFFLOADED,
    717                                               fc_msg);
    718         }
    719 
    720         atomic_inc(&offload_msgs);
    721744        return 0;
    722745}
     
    837860         * Get addressing information, non-NAT first
    838861         */
    839         if (is_v4) {
     862        if (likely(is_v4)) {
    840863                u32 dscp;
    841864
     
    892915        }
    893916#endif
     917
    894918        switch (sic.protocol) {
    895919        case IPPROTO_TCP:
     
    937961        }
    938962
    939         DEBUG_TRACE("POST_ROUTE: checking new connection: %d src_ip: %pIS dst_ip: %pIS, src_port: %d, dst_port: %d\n",
    940                 sic.protocol, &sic.src_ip, &sic.dest_ip, sic.src_port, sic.dest_port);
     963        if (is_v4) {
     964                DEBUG_TRACE("POST_ROUTE: checking new connection: %d src_ip: %pI4 dst_ip: %pI4, src_port: %d, dst_port: %d\n",
     965                            sic.protocol, &sic.src_ip, &sic.dest_ip, sic.src_port, sic.dest_port);
     966        } else {
     967                DEBUG_TRACE("POST_ROUTE: checking new connection: %d src_ip: %pI6 dst_ip: %pI6, src_port: %d, dst_port: %d\n",
     968                            sic.protocol, &sic.src_ip, &sic.dest_ip, sic.src_port, sic.dest_port);
     969        }
    941970
    942971        /*
     
    951980
    952981                if (!conn->offloaded) {
    953                         if (conn->hits >= offload_at_pkts) {
     982                        if (conn->offload_permit || conn->hits >= offload_at_pkts) {
    954983                                DEBUG_TRACE("OFFLOADING CONNECTION, TOO MANY HITS\n");
    955984
     
    9721001                                                fc_msg.src_saddr.in = *((struct in_addr *)&sic.src_ip);
    9731002                                                fc_msg.dst_saddr.in = *((struct in_addr *)&sic.dest_ip_xlate);
    974                                         } else {
     1003                                        }
     1004#ifdef SFE_SUPPORT_IPV6
     1005                                        else {
    9751006                                                fc_msg.ethertype = AF_INET6;
    9761007                                                fc_msg.src_saddr.in6 = *((struct in6_addr *)&sic.src_ip);
    9771008                                                fc_msg.dst_saddr.in6 = *((struct in6_addr *)&sic.dest_ip_xlate);
    9781009                                        }
    979 
     1010#endif
    9801011                                        fc_msg.proto = sic.protocol;
    9811012                                        fc_msg.sport = sic.src_port;
     
    10741105        }
    10751106        conn->hits = 0;
     1107        conn->offload_permit = 0;
    10761108        conn->offloaded = 0;
    10771109        conn->is_v4 = is_v4;
     
    11271159
    11281160#ifdef SFE_SUPPORT_IPV6
     1161
    11291162/*
    11301163 * fast_classifier_ipv6_post_routing_hook()
     
    12061239                sid.dest_ip.ip6[0] = *((struct sfe_ipv6_addr *)&orig_tuple.dst.u3.in6);
    12071240                is_v4 = false;
    1208         } 
     1241        }
    12091242#endif
    12101243        else {
     
    12541287        }
    12551288
    1256         DEBUG_TRACE("Try to clean up: proto: %d src_ip: %pIS dst_ip: %pIS, src_port: %d, dst_port: %d\n",
    1257                 sid.protocol, &sid.src_ip, &sid.dest_ip, sid.src_port, sid.dest_port);
     1289        if (is_v4) {
     1290                DEBUG_TRACE("Try to clean up: proto: %d src_ip: %pI4 dst_ip: %pI4, src_port: %d, dst_port: %d\n",
     1291                            sid.protocol, &sid.src_ip, &sid.dest_ip, sid.src_port, sid.dest_port);
     1292        } else {
     1293                DEBUG_TRACE("Try to clean up: proto: %d src_ip: %pI6 dst_ip: %pI6, src_port: %d, dst_port: %d\n",
     1294                            sid.protocol, &sid.src_ip, &sid.dest_ip, sid.src_port, sid.dest_port);
     1295        }
    12581296
    12591297        spin_lock_bh(&sfe_connections_lock);
     
    12651303                        fc_msg.src_saddr.in = *((struct in_addr *)&conn->sic->src_ip);
    12661304                        fc_msg.dst_saddr.in = *((struct in_addr *)&conn->sic->dest_ip_xlate);
    1267                 } else {
     1305                } else
     1306#ifdef SFE_SUPPORT_IPV6
     1307                {
    12681308                        fc_msg.ethertype = AF_INET6;
    12691309                        fc_msg.src_saddr.in6 = *((struct in6_addr *)&conn->sic->src_ip);
    12701310                        fc_msg.dst_saddr.in6 = *((struct in6_addr *)&conn->sic->dest_ip_xlate);
    12711311                }
    1272 
     1312#endif
    12731313                fc_msg.proto = conn->sic->protocol;
    12741314                fc_msg.sport = conn->sic->src_port;
     
    13431383        tuple.dst.u.all = (__be16)sis->dest_port;
    13441384
     1385#ifdef SFE_SUPPORT_IPV6
    13451386        if (sis->is_v6) {
    13461387                tuple.src.u3.in6 = *((struct in6_addr *)sis->src_ip.ip6);
     
    13521393                            &tuple.src.u3.in6, (unsigned int)ntohs(tuple.src.u.all),
    13531394                            &tuple.dst.u3.in6, (unsigned int)ntohs(tuple.dst.u.all));
    1354         } else {
     1395        } else
     1396#endif
     1397        {
    13551398                tuple.src.u3.ip = sis->src_ip.ip;
    13561399                tuple.dst.u3.ip = sis->dest_ip.ip;
     
    14131456        if (acct) {
    14141457                spin_lock_bh(&ct->lock);
    1415                 atomic64_set(&SFE_ACCT_COUNTER(acct)[IP_CT_DIR_ORIGINAL].packets, sis->src_packet_count);
    1416                 atomic64_set(&SFE_ACCT_COUNTER(acct)[IP_CT_DIR_ORIGINAL].bytes, sis->src_byte_count);
    1417                 atomic64_set(&SFE_ACCT_COUNTER(acct)[IP_CT_DIR_REPLY].packets, sis->dest_packet_count);
    1418                 atomic64_set(&SFE_ACCT_COUNTER(acct)[IP_CT_DIR_REPLY].bytes, sis->dest_byte_count);
     1458                atomic64_add(sis->src_new_packet_count, &SFE_ACCT_COUNTER(acct)[IP_CT_DIR_ORIGINAL].packets);
     1459                atomic64_add(sis->src_new_byte_count, &SFE_ACCT_COUNTER(acct)[IP_CT_DIR_ORIGINAL].bytes);
     1460                atomic64_add(sis->dest_new_packet_count, &SFE_ACCT_COUNTER(acct)[IP_CT_DIR_REPLY].packets);
     1461                atomic64_add(sis->dest_new_byte_count, &SFE_ACCT_COUNTER(acct)[IP_CT_DIR_REPLY].bytes);
    14191462                spin_unlock_bh(&ct->lock);
    14201463        }
     
    14641507#endif
    14651508        }
     1509
    14661510        return NOTIFY_DONE;
    14671511}
     
    14771521                sfe_ipv4_destroy_all_rules_for_dev(dev);
    14781522        }
     1523
    14791524        return NOTIFY_DONE;
    14801525}
    14811526
     1527#ifdef SFE_SUPPORT_IPV6
    14821528/*
    14831529 * fast_classifier_inet6_event()
     
    14901536                sfe_ipv6_destroy_all_rules_for_dev(dev);
    14911537        }
     1538
    14921539        return NOTIFY_DONE;
    14931540}
    1494 
    1495 
     1541#endif
    14961542/*
    14971543 * fast_classifier_get_offload_at_pkts()
     
    15331579        struct sfe_connection *conn;
    15341580        u32 i;
     1581#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0))
     1582        struct hlist_node *node;
     1583#endif
    15351584
    15361585        spin_lock_bh(&sfe_connections_lock);
     
    15441593                        atomic_read(&offloaded_fail_msgs),
    15451594                        atomic_read(&done_fail_msgs));
    1546         sfe_hash_for_each(fc_conn_ht, i, conn, hl) {
     1595        sfe_hash_for_each(fc_conn_ht, i, node, conn, hl) {
    15471596                len += scnprintf(buf + len, PAGE_SIZE - len,
    15481597                                (conn->is_v4 ? "o=%d, p=%d [%pM]:%pI4:%u %pI4:%u:[%pM] m=%08x h=%d\n" : "o=%d, p=%d [%pM]:%pI6:%u %pI6:%u:[%pM] m=%08x h=%d\n"),
     
    16171666 * sysfs attributes.
    16181667 */
    1619 static const struct device_attribute fast_classifier_attrs[] = {
    1620         __ATTR(offload_at_pkts, S_IWUSR | S_IRUGO, fast_classifier_get_offload_at_pkts, fast_classifier_set_offload_at_pkts),
    1621         __ATTR(debug_info, S_IRUGO, fast_classifier_get_debug_info, NULL),
    1622         __ATTR(skip_to_bridge_ingress, S_IWUSR | S_IRUGO, fast_classifier_get_skip_bridge_ingress, fast_classifier_set_skip_bridge_ingress),
    1623         __ATTR(exceptions, S_IRUGO, fast_classifier_get_exceptions, NULL),
    1624 };
     1668static const struct device_attribute fast_classifier_offload_at_pkts_attr =
     1669        __ATTR(offload_at_pkts, S_IWUSR | S_IRUGO, fast_classifier_get_offload_at_pkts, fast_classifier_set_offload_at_pkts);
     1670static const struct device_attribute fast_classifier_debug_info_attr =
     1671        __ATTR(debug_info, S_IRUGO, fast_classifier_get_debug_info, NULL);
     1672static const struct device_attribute fast_classifier_skip_bridge_ingress =
     1673        __ATTR(skip_to_bridge_ingress, S_IWUSR | S_IRUGO, fast_classifier_get_skip_bridge_ingress, fast_classifier_set_skip_bridge_ingress);
     1674static const struct device_attribute fast_classifier_exceptions_attr =
     1675        __ATTR(exceptions, S_IRUGO, fast_classifier_get_exceptions, NULL);
    16251676
    16261677/*
     
    16311682        struct fast_classifier *sc = &__fsc;
    16321683        int result = -1;
    1633         size_t i, j;
    16341684
    16351685        printk(KERN_ALERT "fast-classifier: starting up\n");
     
    16471697        }
    16481698
    1649         for (i = 0; i < ARRAY_SIZE(fast_classifier_attrs); i++) {
    1650                 result = sysfs_create_file(sc->sys_fast_classifier, &fast_classifier_attrs[i].attr);
    1651                 if (result) {
    1652                         DEBUG_ERROR("failed to register %s : %d\n",
    1653                                     fast_classifier_attrs[i].attr.name, result);
    1654                         goto exit2;
    1655                 }
     1699        result = sysfs_create_file(sc->sys_fast_classifier, &fast_classifier_offload_at_pkts_attr.attr);
     1700        if (result) {
     1701                DEBUG_ERROR("failed to register offload at pkgs: %d\n", result);
     1702                goto exit2;
     1703        }
     1704
     1705        result = sysfs_create_file(sc->sys_fast_classifier, &fast_classifier_debug_info_attr.attr);
     1706        if (result) {
     1707                DEBUG_ERROR("failed to register debug dev: %d\n", result);
     1708                sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_offload_at_pkts_attr.attr);
     1709                goto exit2;
     1710        }
     1711
     1712        result = sysfs_create_file(sc->sys_fast_classifier, &fast_classifier_skip_bridge_ingress.attr);
     1713        if (result) {
     1714                DEBUG_ERROR("failed to register skip bridge on ingress: %d\n", result);
     1715                sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_offload_at_pkts_attr.attr);
     1716                sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_debug_info_attr.attr);
     1717                goto exit2;
     1718        }
     1719
     1720        result = sysfs_create_file(sc->sys_fast_classifier, &fast_classifier_exceptions_attr.attr);
     1721        if (result) {
     1722                DEBUG_ERROR("failed to register exceptions file: %d\n", result);
     1723                sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_offload_at_pkts_attr.attr);
     1724                sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_debug_info_attr.attr);
     1725                sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_skip_bridge_ingress.attr);
     1726                goto exit2;
    16561727        }
    16571728
     
    17581829#endif
    17591830        unregister_netdevice_notifier(&sc->dev_notifier);
     1831        sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_offload_at_pkts_attr.attr);
     1832        sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_debug_info_attr.attr);
     1833        sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_skip_bridge_ingress.attr);
     1834        sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_exceptions_attr.attr);
    17601835
    17611836exit2:
    1762         for (j = 0; j < i; j++) {
    1763                 sysfs_remove_file(sc->sys_fast_classifier, &fast_classifier_attrs[j].attr);
    1764         }
    17651837        kobject_put(sc->sys_fast_classifier);
    17661838
     
    18051877        sfe_ipv6_destroy_all_rules_for_dev(NULL);
    18061878#endif
    1807 
    18081879
    18091880#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0))
     
    18341905        kobject_put(sc->sys_fast_classifier);
    18351906}
    1836 
  • src/linux/universal/linux-4.9/net/shortcut-fe/sfe_backport.h

    r32708 r32717  
    134134#endif
    135135
    136 #define sfe_hash_for_each_possible(name, obj, member, key) \
     136#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
     137#define sfe_hash_for_each_possible(name, obj, node, member, key) \
    137138        hash_for_each_possible(name, obj, member, key)
     139#else
     140#define sfe_hash_for_each_possible(name, obj, node, member, key) \
     141        hash_for_each_possible(name, obj, node, member, key)
     142#endif
    138143
    139 #define sfe_hash_for_each(name, bkt, obj, member) \
     144#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
     145#define sfe_hash_for_each(name, bkt, node, obj, member) \
    140146        hash_for_each(name, bkt, obj, member)
     147#else
     148#define sfe_hash_for_each(name, bkt, node, obj, member) \
     149        hash_for_each(name, bkt, node, obj, member)
     150#endif
     151
     152#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
     153#define sfe_dst_get_neighbour(dst, daddr) dst_neigh_lookup(dst, addr)
     154#else
     155static inline struct neighbour *
     156sfe_dst_get_neighbour(struct dst_entry *dst, void *daddr)
     157{
     158        struct neighbour *neigh = dst_get_neighbour_noref(dst);
     159
     160        if (neigh)
     161                neigh_hold(neigh);
     162
     163        return neigh;
     164}
     165#endif
     166
    141167
    142168#endif
Note: See TracChangeset for help on using the changeset viewer.