diff options
-rw-r--r-- | include/linux/netdevice.h | 6 | ||||
-rw-r--r-- | net/core/dev.c | 19 | ||||
-rw-r--r-- | net/ipv4/af_inet.c | 5 | ||||
-rw-r--r-- | net/ipv6/af_inet6.c | 6 |
4 files changed, 20 insertions, 16 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index d45a58db4ba3..61bc8483031f 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -1509,12 +1509,6 @@ struct packet_type { | |||
1509 | struct net_device *, | 1509 | struct net_device *, |
1510 | struct packet_type *, | 1510 | struct packet_type *, |
1511 | struct net_device *); | 1511 | struct net_device *); |
1512 | struct sk_buff *(*gso_segment)(struct sk_buff *skb, | ||
1513 | netdev_features_t features); | ||
1514 | int (*gso_send_check)(struct sk_buff *skb); | ||
1515 | struct sk_buff **(*gro_receive)(struct sk_buff **head, | ||
1516 | struct sk_buff *skb); | ||
1517 | int (*gro_complete)(struct sk_buff *skb); | ||
1518 | bool (*id_match)(struct packet_type *ptype, | 1512 | bool (*id_match)(struct packet_type *ptype, |
1519 | struct sock *sk); | 1513 | struct sock *sk); |
1520 | void *af_packet_priv; | 1514 | void *af_packet_priv; |
diff --git a/net/core/dev.c b/net/core/dev.c index 6884f8783bdd..cf843a256cc6 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2072,7 +2072,7 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, | |||
2072 | netdev_features_t features) | 2072 | netdev_features_t features) |
2073 | { | 2073 | { |
2074 | struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT); | 2074 | struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT); |
2075 | struct packet_type *ptype; | 2075 | struct packet_offload *ptype; |
2076 | __be16 type = skb->protocol; | 2076 | __be16 type = skb->protocol; |
2077 | int vlan_depth = ETH_HLEN; | 2077 | int vlan_depth = ETH_HLEN; |
2078 | int err; | 2078 | int err; |
@@ -2101,9 +2101,8 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, | |||
2101 | } | 2101 | } |
2102 | 2102 | ||
2103 | rcu_read_lock(); | 2103 | rcu_read_lock(); |
2104 | list_for_each_entry_rcu(ptype, | 2104 | list_for_each_entry_rcu(ptype, &offload_base, list) { |
2105 | &ptype_base[ntohs(type) & PTYPE_HASH_MASK], list) { | 2105 | if (ptype->type == type && ptype->gso_segment) { |
2106 | if (ptype->type == type && !ptype->dev && ptype->gso_segment) { | ||
2107 | if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) { | 2106 | if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) { |
2108 | err = ptype->gso_send_check(skb); | 2107 | err = ptype->gso_send_check(skb); |
2109 | segs = ERR_PTR(err); | 2108 | segs = ERR_PTR(err); |
@@ -3522,9 +3521,9 @@ static void flush_backlog(void *arg) | |||
3522 | 3521 | ||
3523 | static int napi_gro_complete(struct sk_buff *skb) | 3522 | static int napi_gro_complete(struct sk_buff *skb) |
3524 | { | 3523 | { |
3525 | struct packet_type *ptype; | 3524 | struct packet_offload *ptype; |
3526 | __be16 type = skb->protocol; | 3525 | __be16 type = skb->protocol; |
3527 | struct list_head *head = &ptype_base[ntohs(type) & PTYPE_HASH_MASK]; | 3526 | struct list_head *head = &offload_base; |
3528 | int err = -ENOENT; | 3527 | int err = -ENOENT; |
3529 | 3528 | ||
3530 | if (NAPI_GRO_CB(skb)->count == 1) { | 3529 | if (NAPI_GRO_CB(skb)->count == 1) { |
@@ -3534,7 +3533,7 @@ static int napi_gro_complete(struct sk_buff *skb) | |||
3534 | 3533 | ||
3535 | rcu_read_lock(); | 3534 | rcu_read_lock(); |
3536 | list_for_each_entry_rcu(ptype, head, list) { | 3535 | list_for_each_entry_rcu(ptype, head, list) { |
3537 | if (ptype->type != type || ptype->dev || !ptype->gro_complete) | 3536 | if (ptype->type != type || !ptype->gro_complete) |
3538 | continue; | 3537 | continue; |
3539 | 3538 | ||
3540 | err = ptype->gro_complete(skb); | 3539 | err = ptype->gro_complete(skb); |
@@ -3584,9 +3583,9 @@ EXPORT_SYMBOL(napi_gro_flush); | |||
3584 | enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb) | 3583 | enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb) |
3585 | { | 3584 | { |
3586 | struct sk_buff **pp = NULL; | 3585 | struct sk_buff **pp = NULL; |
3587 | struct packet_type *ptype; | 3586 | struct packet_offload *ptype; |
3588 | __be16 type = skb->protocol; | 3587 | __be16 type = skb->protocol; |
3589 | struct list_head *head = &ptype_base[ntohs(type) & PTYPE_HASH_MASK]; | 3588 | struct list_head *head = &offload_base; |
3590 | int same_flow; | 3589 | int same_flow; |
3591 | int mac_len; | 3590 | int mac_len; |
3592 | enum gro_result ret; | 3591 | enum gro_result ret; |
@@ -3599,7 +3598,7 @@ enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb) | |||
3599 | 3598 | ||
3600 | rcu_read_lock(); | 3599 | rcu_read_lock(); |
3601 | list_for_each_entry_rcu(ptype, head, list) { | 3600 | list_for_each_entry_rcu(ptype, head, list) { |
3602 | if (ptype->type != type || ptype->dev || !ptype->gro_receive) | 3601 | if (ptype->type != type || !ptype->gro_receive) |
3603 | continue; | 3602 | continue; |
3604 | 3603 | ||
3605 | skb_set_network_header(skb, skb_gro_offset(skb)); | 3604 | skb_set_network_header(skb, skb_gro_offset(skb)); |
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 766c59658563..4c99c5fdba3f 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
@@ -1662,6 +1662,10 @@ static int ipv4_proc_init(void); | |||
1662 | static struct packet_type ip_packet_type __read_mostly = { | 1662 | static struct packet_type ip_packet_type __read_mostly = { |
1663 | .type = cpu_to_be16(ETH_P_IP), | 1663 | .type = cpu_to_be16(ETH_P_IP), |
1664 | .func = ip_rcv, | 1664 | .func = ip_rcv, |
1665 | }; | ||
1666 | |||
1667 | static struct packet_offload ip_packet_offload __read_mostly = { | ||
1668 | .type = cpu_to_be16(ETH_P_IP), | ||
1665 | .gso_send_check = inet_gso_send_check, | 1669 | .gso_send_check = inet_gso_send_check, |
1666 | .gso_segment = inet_gso_segment, | 1670 | .gso_segment = inet_gso_segment, |
1667 | .gro_receive = inet_gro_receive, | 1671 | .gro_receive = inet_gro_receive, |
@@ -1781,6 +1785,7 @@ static int __init inet_init(void) | |||
1781 | 1785 | ||
1782 | ipfrag_init(); | 1786 | ipfrag_init(); |
1783 | 1787 | ||
1788 | dev_add_offload(&ip_packet_offload); | ||
1784 | dev_add_pack(&ip_packet_type); | 1789 | dev_add_pack(&ip_packet_type); |
1785 | 1790 | ||
1786 | rc = 0; | 1791 | rc = 0; |
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index a974247a9ae4..6e245177608c 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
@@ -938,6 +938,10 @@ out_unlock: | |||
938 | static struct packet_type ipv6_packet_type __read_mostly = { | 938 | static struct packet_type ipv6_packet_type __read_mostly = { |
939 | .type = cpu_to_be16(ETH_P_IPV6), | 939 | .type = cpu_to_be16(ETH_P_IPV6), |
940 | .func = ipv6_rcv, | 940 | .func = ipv6_rcv, |
941 | }; | ||
942 | |||
943 | static struct packet_offload ipv6_packet_offload __read_mostly = { | ||
944 | .type = cpu_to_be16(ETH_P_IPV6), | ||
941 | .gso_send_check = ipv6_gso_send_check, | 945 | .gso_send_check = ipv6_gso_send_check, |
942 | .gso_segment = ipv6_gso_segment, | 946 | .gso_segment = ipv6_gso_segment, |
943 | .gro_receive = ipv6_gro_receive, | 947 | .gro_receive = ipv6_gro_receive, |
@@ -946,6 +950,7 @@ static struct packet_type ipv6_packet_type __read_mostly = { | |||
946 | 950 | ||
947 | static int __init ipv6_packet_init(void) | 951 | static int __init ipv6_packet_init(void) |
948 | { | 952 | { |
953 | dev_add_offload(&ipv6_packet_offload); | ||
949 | dev_add_pack(&ipv6_packet_type); | 954 | dev_add_pack(&ipv6_packet_type); |
950 | return 0; | 955 | return 0; |
951 | } | 956 | } |
@@ -953,6 +958,7 @@ static int __init ipv6_packet_init(void) | |||
953 | static void ipv6_packet_cleanup(void) | 958 | static void ipv6_packet_cleanup(void) |
954 | { | 959 | { |
955 | dev_remove_pack(&ipv6_packet_type); | 960 | dev_remove_pack(&ipv6_packet_type); |
961 | dev_remove_offload(&ipv6_packet_offload); | ||
956 | } | 962 | } |
957 | 963 | ||
958 | static int __net_init ipv6_init_mibs(struct net *net) | 964 | static int __net_init ipv6_init_mibs(struct net *net) |