diff options
Diffstat (limited to 'net/core')
| -rw-r--r-- | net/core/dev.c | 2 | ||||
| -rw-r--r-- | net/core/drop_monitor.c | 1 | ||||
| -rw-r--r-- | net/core/iovec.c | 3 | ||||
| -rw-r--r-- | net/core/pktgen.c | 7 | ||||
| -rw-r--r-- | net/core/skbuff.c | 76 | ||||
| -rw-r--r-- | net/core/sock.c | 2 |
6 files changed, 62 insertions, 29 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 7e00a7342ee6..ba3b7ea5ebb3 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -4996,7 +4996,7 @@ static void dev_change_rx_flags(struct net_device *dev, int flags) | |||
| 4996 | { | 4996 | { |
| 4997 | const struct net_device_ops *ops = dev->netdev_ops; | 4997 | const struct net_device_ops *ops = dev->netdev_ops; |
| 4998 | 4998 | ||
| 4999 | if ((dev->flags & IFF_UP) && ops->ndo_change_rx_flags) | 4999 | if (ops->ndo_change_rx_flags) |
| 5000 | ops->ndo_change_rx_flags(dev, flags); | 5000 | ops->ndo_change_rx_flags(dev, flags); |
| 5001 | } | 5001 | } |
| 5002 | 5002 | ||
diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c index 95897183226e..e70301eb7a4a 100644 --- a/net/core/drop_monitor.c +++ b/net/core/drop_monitor.c | |||
| @@ -64,7 +64,6 @@ static struct genl_family net_drop_monitor_family = { | |||
| 64 | .hdrsize = 0, | 64 | .hdrsize = 0, |
| 65 | .name = "NET_DM", | 65 | .name = "NET_DM", |
| 66 | .version = 2, | 66 | .version = 2, |
| 67 | .maxattr = NET_DM_CMD_MAX, | ||
| 68 | }; | 67 | }; |
| 69 | 68 | ||
| 70 | static DEFINE_PER_CPU(struct per_cpu_dm_data, dm_cpu_data); | 69 | static DEFINE_PER_CPU(struct per_cpu_dm_data, dm_cpu_data); |
diff --git a/net/core/iovec.c b/net/core/iovec.c index 4cdb7c48dad6..b61869429f4c 100644 --- a/net/core/iovec.c +++ b/net/core/iovec.c | |||
| @@ -48,7 +48,8 @@ int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr_storage *a | |||
| 48 | if (err < 0) | 48 | if (err < 0) |
| 49 | return err; | 49 | return err; |
| 50 | } | 50 | } |
| 51 | m->msg_name = address; | 51 | if (m->msg_name) |
| 52 | m->msg_name = address; | ||
| 52 | } else { | 53 | } else { |
| 53 | m->msg_name = NULL; | 54 | m->msg_name = NULL; |
| 54 | } | 55 | } |
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 261357a66300..a797fff7f222 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c | |||
| @@ -2527,6 +2527,8 @@ static int process_ipsec(struct pktgen_dev *pkt_dev, | |||
| 2527 | if (x) { | 2527 | if (x) { |
| 2528 | int ret; | 2528 | int ret; |
| 2529 | __u8 *eth; | 2529 | __u8 *eth; |
| 2530 | struct iphdr *iph; | ||
| 2531 | |||
| 2530 | nhead = x->props.header_len - skb_headroom(skb); | 2532 | nhead = x->props.header_len - skb_headroom(skb); |
| 2531 | if (nhead > 0) { | 2533 | if (nhead > 0) { |
| 2532 | ret = pskb_expand_head(skb, nhead, 0, GFP_ATOMIC); | 2534 | ret = pskb_expand_head(skb, nhead, 0, GFP_ATOMIC); |
| @@ -2548,6 +2550,11 @@ static int process_ipsec(struct pktgen_dev *pkt_dev, | |||
| 2548 | eth = (__u8 *) skb_push(skb, ETH_HLEN); | 2550 | eth = (__u8 *) skb_push(skb, ETH_HLEN); |
| 2549 | memcpy(eth, pkt_dev->hh, 12); | 2551 | memcpy(eth, pkt_dev->hh, 12); |
| 2550 | *(u16 *) ð[12] = protocol; | 2552 | *(u16 *) ð[12] = protocol; |
| 2553 | |||
| 2554 | /* Update IPv4 header len as well as checksum value */ | ||
| 2555 | iph = ip_hdr(skb); | ||
| 2556 | iph->tot_len = htons(skb->len - ETH_HLEN); | ||
| 2557 | ip_send_check(iph); | ||
| 2551 | } | 2558 | } |
| 2552 | } | 2559 | } |
| 2553 | return 1; | 2560 | return 1; |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 8cec1e6b844d..06e72d3cdf60 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
| @@ -2796,6 +2796,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features) | |||
| 2796 | struct sk_buff *segs = NULL; | 2796 | struct sk_buff *segs = NULL; |
| 2797 | struct sk_buff *tail = NULL; | 2797 | struct sk_buff *tail = NULL; |
| 2798 | struct sk_buff *fskb = skb_shinfo(skb)->frag_list; | 2798 | struct sk_buff *fskb = skb_shinfo(skb)->frag_list; |
| 2799 | skb_frag_t *skb_frag = skb_shinfo(skb)->frags; | ||
| 2799 | unsigned int mss = skb_shinfo(skb)->gso_size; | 2800 | unsigned int mss = skb_shinfo(skb)->gso_size; |
| 2800 | unsigned int doffset = skb->data - skb_mac_header(skb); | 2801 | unsigned int doffset = skb->data - skb_mac_header(skb); |
| 2801 | unsigned int offset = doffset; | 2802 | unsigned int offset = doffset; |
| @@ -2835,16 +2836,38 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features) | |||
| 2835 | if (hsize > len || !sg) | 2836 | if (hsize > len || !sg) |
| 2836 | hsize = len; | 2837 | hsize = len; |
| 2837 | 2838 | ||
| 2838 | if (!hsize && i >= nfrags) { | 2839 | if (!hsize && i >= nfrags && skb_headlen(fskb) && |
| 2839 | BUG_ON(fskb->len != len); | 2840 | (skb_headlen(fskb) == len || sg)) { |
| 2841 | BUG_ON(skb_headlen(fskb) > len); | ||
| 2842 | |||
| 2843 | i = 0; | ||
| 2844 | nfrags = skb_shinfo(fskb)->nr_frags; | ||
| 2845 | skb_frag = skb_shinfo(fskb)->frags; | ||
| 2846 | pos += skb_headlen(fskb); | ||
| 2847 | |||
| 2848 | while (pos < offset + len) { | ||
| 2849 | BUG_ON(i >= nfrags); | ||
| 2850 | |||
| 2851 | size = skb_frag_size(skb_frag); | ||
| 2852 | if (pos + size > offset + len) | ||
| 2853 | break; | ||
| 2854 | |||
| 2855 | i++; | ||
| 2856 | pos += size; | ||
| 2857 | skb_frag++; | ||
| 2858 | } | ||
| 2840 | 2859 | ||
| 2841 | pos += len; | ||
| 2842 | nskb = skb_clone(fskb, GFP_ATOMIC); | 2860 | nskb = skb_clone(fskb, GFP_ATOMIC); |
| 2843 | fskb = fskb->next; | 2861 | fskb = fskb->next; |
| 2844 | 2862 | ||
| 2845 | if (unlikely(!nskb)) | 2863 | if (unlikely(!nskb)) |
| 2846 | goto err; | 2864 | goto err; |
| 2847 | 2865 | ||
| 2866 | if (unlikely(pskb_trim(nskb, len))) { | ||
| 2867 | kfree_skb(nskb); | ||
| 2868 | goto err; | ||
| 2869 | } | ||
| 2870 | |||
| 2848 | hsize = skb_end_offset(nskb); | 2871 | hsize = skb_end_offset(nskb); |
| 2849 | if (skb_cow_head(nskb, doffset + headroom)) { | 2872 | if (skb_cow_head(nskb, doffset + headroom)) { |
| 2850 | kfree_skb(nskb); | 2873 | kfree_skb(nskb); |
| @@ -2881,7 +2904,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features) | |||
| 2881 | nskb->data - tnl_hlen, | 2904 | nskb->data - tnl_hlen, |
| 2882 | doffset + tnl_hlen); | 2905 | doffset + tnl_hlen); |
| 2883 | 2906 | ||
| 2884 | if (fskb != skb_shinfo(skb)->frag_list) | 2907 | if (nskb->len == len + doffset) |
| 2885 | goto perform_csum_check; | 2908 | goto perform_csum_check; |
| 2886 | 2909 | ||
| 2887 | if (!sg) { | 2910 | if (!sg) { |
| @@ -2899,8 +2922,28 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features) | |||
| 2899 | 2922 | ||
| 2900 | skb_shinfo(nskb)->tx_flags = skb_shinfo(skb)->tx_flags & SKBTX_SHARED_FRAG; | 2923 | skb_shinfo(nskb)->tx_flags = skb_shinfo(skb)->tx_flags & SKBTX_SHARED_FRAG; |
| 2901 | 2924 | ||
| 2902 | while (pos < offset + len && i < nfrags) { | 2925 | while (pos < offset + len) { |
| 2903 | *frag = skb_shinfo(skb)->frags[i]; | 2926 | if (i >= nfrags) { |
| 2927 | BUG_ON(skb_headlen(fskb)); | ||
| 2928 | |||
| 2929 | i = 0; | ||
| 2930 | nfrags = skb_shinfo(fskb)->nr_frags; | ||
| 2931 | skb_frag = skb_shinfo(fskb)->frags; | ||
| 2932 | |||
| 2933 | BUG_ON(!nfrags); | ||
| 2934 | |||
| 2935 | fskb = fskb->next; | ||
| 2936 | } | ||
| 2937 | |||
| 2938 | if (unlikely(skb_shinfo(nskb)->nr_frags >= | ||
| 2939 | MAX_SKB_FRAGS)) { | ||
| 2940 | net_warn_ratelimited( | ||
| 2941 | "skb_segment: too many frags: %u %u\n", | ||
| 2942 | pos, mss); | ||
| 2943 | goto err; | ||
| 2944 | } | ||
| 2945 | |||
| 2946 | *frag = *skb_frag; | ||
| 2904 | __skb_frag_ref(frag); | 2947 | __skb_frag_ref(frag); |
| 2905 | size = skb_frag_size(frag); | 2948 | size = skb_frag_size(frag); |
| 2906 | 2949 | ||
| @@ -2913,6 +2956,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features) | |||
| 2913 | 2956 | ||
| 2914 | if (pos + size <= offset + len) { | 2957 | if (pos + size <= offset + len) { |
| 2915 | i++; | 2958 | i++; |
| 2959 | skb_frag++; | ||
| 2916 | pos += size; | 2960 | pos += size; |
| 2917 | } else { | 2961 | } else { |
| 2918 | skb_frag_size_sub(frag, pos + size - (offset + len)); | 2962 | skb_frag_size_sub(frag, pos + size - (offset + len)); |
| @@ -2922,25 +2966,6 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features) | |||
| 2922 | frag++; | 2966 | frag++; |
| 2923 | } | 2967 | } |
| 2924 | 2968 | ||
| 2925 | if (pos < offset + len) { | ||
| 2926 | struct sk_buff *fskb2 = fskb; | ||
| 2927 | |||
| 2928 | BUG_ON(pos + fskb->len != offset + len); | ||
| 2929 | |||
| 2930 | pos += fskb->len; | ||
| 2931 | fskb = fskb->next; | ||
| 2932 | |||
| 2933 | if (fskb2->next) { | ||
| 2934 | fskb2 = skb_clone(fskb2, GFP_ATOMIC); | ||
| 2935 | if (!fskb2) | ||
| 2936 | goto err; | ||
| 2937 | } else | ||
| 2938 | skb_get(fskb2); | ||
| 2939 | |||
| 2940 | SKB_FRAG_ASSERT(nskb); | ||
| 2941 | skb_shinfo(nskb)->frag_list = fskb2; | ||
| 2942 | } | ||
| 2943 | |||
| 2944 | skip_fraglist: | 2969 | skip_fraglist: |
| 2945 | nskb->data_len = len - hsize; | 2970 | nskb->data_len = len - hsize; |
| 2946 | nskb->len += nskb->data_len; | 2971 | nskb->len += nskb->data_len; |
| @@ -3559,6 +3584,7 @@ void skb_scrub_packet(struct sk_buff *skb, bool xnet) | |||
| 3559 | skb->tstamp.tv64 = 0; | 3584 | skb->tstamp.tv64 = 0; |
| 3560 | skb->pkt_type = PACKET_HOST; | 3585 | skb->pkt_type = PACKET_HOST; |
| 3561 | skb->skb_iif = 0; | 3586 | skb->skb_iif = 0; |
| 3587 | skb->local_df = 0; | ||
| 3562 | skb_dst_drop(skb); | 3588 | skb_dst_drop(skb); |
| 3563 | skb->mark = 0; | 3589 | skb->mark = 0; |
| 3564 | secpath_reset(skb); | 3590 | secpath_reset(skb); |
diff --git a/net/core/sock.c b/net/core/sock.c index ab20ed9b0f31..5393b4b719d7 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
| @@ -882,7 +882,7 @@ set_rcvbuf: | |||
| 882 | 882 | ||
| 883 | case SO_PEEK_OFF: | 883 | case SO_PEEK_OFF: |
| 884 | if (sock->ops->set_peek_off) | 884 | if (sock->ops->set_peek_off) |
| 885 | sock->ops->set_peek_off(sk, val); | 885 | ret = sock->ops->set_peek_off(sk, val); |
| 886 | else | 886 | else |
| 887 | ret = -EOPNOTSUPP; | 887 | ret = -EOPNOTSUPP; |
| 888 | break; | 888 | break; |
