--- zzzz-none-000/linux-4.4.271/net/core/dev.c 2021-06-03 06:22:09.000000000 +0000 +++ hawkeye-5590-750/linux-4.4.271/net/core/dev.c 2023-04-19 10:22:30.000000000 +0000 @@ -98,6 +98,7 @@ #include #include #include +#include #include #include #include @@ -140,6 +141,7 @@ #include #include "net-sysfs.h" +#include "skbuff_debug.h" /* Instead of increasing this, you should create a hash table. */ #define MAX_GRO_SKBS 8 @@ -158,6 +160,9 @@ struct net_device *dev, struct netdev_notifier_info *info); +static int (*avm_recvhook)(struct sk_buff *skb); +static int (*avm_early_recvhook)(struct sk_buff *skb); + /* * The @dev_base_head list is protected by @dev_base_lock and the rtnl * semaphore. @@ -355,6 +360,18 @@ *******************************************************************************/ +void set_avm_recvhook(int (*recvhook)(struct sk_buff *skb)) +{ + avm_recvhook = recvhook; +} +EXPORT_SYMBOL(set_avm_recvhook); + +void set_avm_early_recvhook(int (*recvhook)(struct sk_buff *skb)) +{ + avm_early_recvhook = recvhook; +} +EXPORT_SYMBOL(set_avm_early_recvhook); + /* * Add a protocol ID to the list. Now that the input handler is * smarter we can dispense with all the messy stuff that used to be @@ -514,6 +531,7 @@ out: spin_unlock(&offload_lock); } +EXPORT_SYMBOL(__dev_remove_offload); /** * dev_remove_offload - remove packet offload handler @@ -1874,7 +1892,7 @@ * taps currently in use. */ -static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev) +void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev) { struct packet_type *ptype; struct sk_buff *skb2 = NULL; @@ -1931,6 +1949,7 @@ pt_prev->func(skb2, skb->dev, pt_prev, skb->dev); rcu_read_unlock(); } +EXPORT_SYMBOL_GPL(dev_queue_xmit_nit); /** * netif_setup_tc - Handle tc mappings on real_num_tx_queues change @@ -2769,13 +2788,36 @@ unsigned int len; int rc; - if (!list_empty(&ptype_all) || !list_empty(&dev->ptype_all)) - dev_queue_xmit_nit(skb, dev); + /* At this point all offload features are handled and the skb is + * optimized for the driver. + */ + avm_pa_dev_snoop_transmit(AVM_PA_DEVINFO(dev), skb); - len = skb->len; - trace_net_dev_start_xmit(skb, dev); - rc = netdev_start_xmit(skb, dev, txq, more); - trace_net_dev_xmit(skb, rc, dev, len); + /* If this skb has been fast forwarded then we don't want it to + * go to any taps (by definition we're trying to bypass them). + */ + if (unlikely(!skb->fast_forwarded)) { + if (!list_empty(&ptype_all) || !list_empty(&dev->ptype_all)) + dev_queue_xmit_nit(skb, dev); + } + +#ifdef CONFIG_ETHERNET_PACKET_MANGLE + if (!dev->eth_mangle_tx || + (skb = dev->eth_mangle_tx(dev, skb)) != NULL) +#else + if (1) +#endif + { + len = skb->len; + trace_net_dev_start_xmit(skb, dev); +#ifdef CONFIG_NET_DEBUG_SKBUFF_LEAK + skb_track_funccall(skb, ops->ndo_start_xmit); +#endif + rc = netdev_start_xmit(skb, dev, txq, more); + trace_net_dev_xmit(skb, rc, dev, len); + } else { + rc = NETDEV_TX_OK; + } return rc; } @@ -2983,6 +3025,7 @@ rc = NET_XMIT_SUCCESS; } else { + avm_pa_mark_shaped(skb); rc = q->enqueue(skb, q) & NET_XMIT_MASK; if (qdisc_run_begin(q)) { if (unlikely(contended)) { @@ -3152,6 +3195,10 @@ struct Qdisc *q; int rc = -ENOMEM; +#ifdef CONFIG_NET_DEBUG_SKBUFF_LEAK + skb_track_caller(skb); +#endif + skb_reset_mac_header(skb); if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_SCHED_TSTAMP)) @@ -3607,6 +3654,10 @@ { int ret; +#ifdef CONFIG_NET_DEBUG_SKBUFF_LEAK + skb_track_caller(skb); +#endif + net_timestamp_check(netdev_tstamp_prequeue, skb); trace_netif_rx(skb); @@ -3863,6 +3914,9 @@ } EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister); +int (*athrs_fast_nat_recv)(struct sk_buff *skb) __rcu __read_mostly; +EXPORT_SYMBOL_GPL(athrs_fast_nat_recv); + /* * Limit the use of PFMEMALLOC reserves to those protocols that implement * the special handling of PFMEMALLOC skbs. @@ -3905,6 +3959,7 @@ bool deliver_exact = false; int ret = NET_RX_DROP; __be16 type; + int (*fast_recv)(struct sk_buff *skb); net_timestamp_check(!netdev_tstamp_prequeue, skb); @@ -3919,6 +3974,11 @@ pt_prev = NULL; +#if IS_ENABLED(CONFIG_AVM_NET_SKB_INPUT_DEV) + if (!skb->input_dev) + skb->input_dev = skb->dev; +#endif + another_round: skb->skb_iif = skb->dev->ifindex; @@ -3931,6 +3991,14 @@ goto out; } + fast_recv = rcu_dereference(athrs_fast_nat_recv); + if (fast_recv) { + if (fast_recv(skb)) { + ret = NET_RX_SUCCESS; + goto out; + } + } + #ifdef CONFIG_NET_CLS_ACT if (skb->tc_verd & TC_NCLS) { skb->tc_verd = CLR_TC_NCLS(skb->tc_verd); @@ -3971,6 +4039,23 @@ if (pfmemalloc && !skb_pfmemalloc_protocol(skb)) goto drop; +#ifdef CONFIG_AVM_NET_DEBUG_SKBUFF_LEAK + skb_track_funccall(skb, avm_pa_dev_receive); +#endif + + if (avm_pa_dev_receive(AVM_PA_DEVINFO(skb->dev), skb) == 0) { + ret = NET_RX_SUCCESS; + goto out; + } + + if (avm_early_recvhook && (*avm_early_recvhook)(skb)) { + /* + * paket consumed by hook + */ + ret = NET_RX_SUCCESS; + goto out; + } + if (skb_vlan_tag_present(skb)) { if (pt_prev) { ret = deliver_skb(skb, pt_prev, orig_dev); @@ -4013,6 +4098,14 @@ skb->vlan_tci = 0; } + if (skb && avm_recvhook && (*avm_recvhook)(skb)) { + /* + * paket consumed by hook + */ + ret = NET_RX_SUCCESS; + goto out; + } + type = skb->protocol; /* deliver only exact match when indicated */ @@ -4296,6 +4389,9 @@ enum gro_result ret; int grow; + if (skb->gro_skip) + goto normal; + if (!(skb->dev->features & NETIF_F_GRO)) goto normal; @@ -4442,10 +4538,12 @@ break; case GRO_MERGED_FREE: - if (NAPI_GRO_CB(skb)->free == NAPI_GRO_FREE_STOLEN_HEAD) + if (NAPI_GRO_CB(skb)->free == NAPI_GRO_FREE_STOLEN_HEAD) { napi_skb_free_stolen_head(skb); - else + skbuff_debugobj_deactivate(skb); + } else { __kfree_skb(skb); + } break; case GRO_HELD: @@ -4887,6 +4985,14 @@ } EXPORT_SYMBOL(netif_napi_del); +struct napi_struct *get_current_napi_context(void) +{ + struct softnet_data *sd = this_cpu_ptr(&softnet_data); + + return sd->current_napi; +} +EXPORT_SYMBOL(get_current_napi_context); + static int napi_poll(struct napi_struct *n, struct list_head *repoll) { void *have; @@ -5468,6 +5574,48 @@ &upper_dev->adj_list.lower); } +static void __netdev_addr_mask(unsigned char *mask, const unsigned char *addr, + struct net_device *dev) +{ + int i; + + for (i = 0; i < dev->addr_len; i++) + mask[i] |= addr[i] ^ dev->dev_addr[i]; +} + +static void __netdev_upper_mask(unsigned char *mask, struct net_device *dev, + struct net_device *lower) +{ + struct net_device *cur; + struct list_head *iter; + + netdev_for_each_upper_dev_rcu(dev, cur, iter) { + __netdev_addr_mask(mask, cur->dev_addr, lower); + __netdev_upper_mask(mask, cur, lower); + } +} + +static void __netdev_update_addr_mask(struct net_device *dev) +{ + unsigned char mask[MAX_ADDR_LEN]; + struct net_device *cur; + struct list_head *iter; + + memset(mask, 0, sizeof(mask)); + __netdev_upper_mask(mask, dev, dev); + memcpy(dev->local_addr_mask, mask, dev->addr_len); + + netdev_for_each_lower_dev(dev, cur, iter) + __netdev_update_addr_mask(cur); +} + +static void netdev_update_addr_mask(struct net_device *dev) +{ + rcu_read_lock(); + __netdev_update_addr_mask(dev); + rcu_read_unlock(); +} + static int __netdev_upper_dev_link(struct net_device *dev, struct net_device *upper_dev, bool master, void *private) @@ -5539,6 +5687,7 @@ goto rollback_lower_mesh; } + netdev_update_addr_mask(dev); call_netdevice_notifiers_info(NETDEV_CHANGEUPPER, dev, &changeupper_info.info); return 0; @@ -5665,6 +5814,7 @@ list_for_each_entry(i, &upper_dev->all_adj_list.upper, list) __netdev_adjacent_dev_unlink(dev, i->dev, i->ref_nr); + netdev_update_addr_mask(dev); call_netdevice_notifiers_info(NETDEV_CHANGEUPPER, dev, &changeupper_info.info); } @@ -6208,6 +6358,7 @@ if (err) return err; dev->addr_assign_type = NET_ADDR_SET; + netdev_update_addr_mask(dev); call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); add_device_randomness(dev->dev_addr, dev->addr_len); return 0; @@ -6521,6 +6672,18 @@ #endif features &= ~NETIF_F_BUSY_POLL; + if (!(features & NETIF_F_RXCSUM)) { + /* NETIF_F_GRO_HW implies doing RXCSUM since every packet + * successfully merged by hardware must also have the + * checksum verified by hardware. If the user does not + * want to enable RXCSUM, logically, we should disable GRO_HW. + */ + if (features & NETIF_F_GRO_HW) { + netdev_dbg(dev, "Dropping NETIF_F_GRO_HW since no RXCSUM feature.\n"); + features &= ~NETIF_F_GRO_HW; + } + } + return features; } @@ -7061,6 +7224,7 @@ dev->reg_state = NETREG_UNREGISTERED; netdev_wait_allrefs(dev); + avm_pa_dev_unregister_sync(AVM_PA_DEVINFO(dev)); /* paranoia */ BUG_ON(netdev_refcnt_read(dev)); @@ -7069,7 +7233,6 @@ WARN_ON(rcu_access_pointer(dev->ip_ptr)); WARN_ON(rcu_access_pointer(dev->ip6_ptr)); WARN_ON(dev->dn_ptr); - if (dev->destructor) dev->destructor(dev); @@ -7251,6 +7414,7 @@ INIT_LIST_HEAD(&dev->ptype_all); INIT_LIST_HEAD(&dev->ptype_specific); dev->priv_flags = IFF_XMIT_DST_RELEASE | IFF_XMIT_DST_RELEASE_PERM; + avm_pa_dev_init(AVM_PA_DEVINFO(dev)); setup(dev); if (!dev->tx_queue_len) {