mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-24 13:13:57 +08:00
b2d0f5d5dc
v16->17 - Fixed disputed check code: keep them in nsh_push and nsh_pop but also add them in __ovs_nla_copy_actions v15->v16 - Add csum recalculation for nsh_push, nsh_pop and set_nsh pointed out by Pravin - Move nsh key into the union with ipv4 and ipv6 and add check for nsh key in match_validate pointed out by Pravin - Add nsh check in validate_set and __ovs_nla_copy_actions v14->v15 - Check size in nsh_hdr_from_nlattr - Fixed four small issues pointed out By Jiri and Eric v13->v14 - Rename skb_push_nsh to nsh_push per Dave's comment - Rename skb_pop_nsh to nsh_pop per Dave's comment v12->v13 - Fix NSH header length check in set_nsh v11->v12 - Fix missing changes old comments pointed out - Fix new comments for v11 v10->v11 - Fix the left three disputable comments for v9 but not fixed in v10. v9->v10 - Change struct ovs_key_nsh to struct ovs_nsh_key_base base; __be32 context[NSH_MD1_CONTEXT_SIZE]; - Fix new comments for v9 v8->v9 - Fix build error reported by daily intel build because nsh module isn't selected by openvswitch v7->v8 - Rework nested value and mask for OVS_KEY_ATTR_NSH - Change pop_nsh to adapt to nsh kernel module - Fix many issues per comments from Jiri Benc v6->v7 - Remove NSH GSO patches in v6 because Jiri Benc reworked it as another patch series and they have been merged. - Change it to adapt to nsh kernel module added by NSH GSO patch series v5->v6 - Fix the rest comments for v4. - Add NSH GSO support for VxLAN-gpe + NSH and Eth + NSH. v4->v5 - Fix many comments by Jiri Benc and Eric Garver for v4. v3->v4 - Add new NSH match field ttl - Update NSH header to the latest format which will be final format and won't change per its author's confirmation. - Fix comments for v3. v2->v3 - Change OVS_KEY_ATTR_NSH to nested key to handle length-fixed attributes and length-variable attriubte more flexibly. - Remove struct ovs_action_push_nsh completely - Add code to handle nested attribute for SET_MASKED - Change PUSH_NSH to use the nested OVS_KEY_ATTR_NSH to transfer NSH header data. - Fix comments and coding style issues by Jiri and Eric v1->v2 - Change encap_nsh and decap_nsh to push_nsh and pop_nsh - Dynamically allocate struct ovs_action_push_nsh for length-variable metadata. OVS master and 2.8 branch has merged NSH userspace patch series, this patch is to enable NSH support in kernel data path in order that OVS can support NSH in compat mode by porting this. Signed-off-by: Yi Yang <yi.y.yang@intel.com> Acked-by: Jiri Benc <jbenc@redhat.com> Acked-by: Eric Garver <e@erig.me> Acked-by: Pravin Shelar <pshelar@ovn.org> Signed-off-by: David S. Miller <davem@davemloft.net>
152 lines
3.2 KiB
C
152 lines
3.2 KiB
C
/*
|
|
* Network Service Header
|
|
*
|
|
* Copyright (c) 2017 Red Hat, Inc. -- Jiri Benc <jbenc@redhat.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*/
|
|
|
|
#include <linux/module.h>
|
|
#include <linux/netdevice.h>
|
|
#include <linux/skbuff.h>
|
|
#include <net/nsh.h>
|
|
#include <net/tun_proto.h>
|
|
|
|
int nsh_push(struct sk_buff *skb, const struct nshhdr *pushed_nh)
|
|
{
|
|
struct nshhdr *nh;
|
|
size_t length = nsh_hdr_len(pushed_nh);
|
|
u8 next_proto;
|
|
|
|
if (skb->mac_len) {
|
|
next_proto = TUN_P_ETHERNET;
|
|
} else {
|
|
next_proto = tun_p_from_eth_p(skb->protocol);
|
|
if (!next_proto)
|
|
return -EAFNOSUPPORT;
|
|
}
|
|
|
|
/* Add the NSH header */
|
|
if (skb_cow_head(skb, length) < 0)
|
|
return -ENOMEM;
|
|
|
|
skb_push(skb, length);
|
|
nh = (struct nshhdr *)(skb->data);
|
|
memcpy(nh, pushed_nh, length);
|
|
nh->np = next_proto;
|
|
skb_postpush_rcsum(skb, nh, length);
|
|
|
|
skb->protocol = htons(ETH_P_NSH);
|
|
skb_reset_mac_header(skb);
|
|
skb_reset_network_header(skb);
|
|
skb_reset_mac_len(skb);
|
|
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL_GPL(nsh_push);
|
|
|
|
int nsh_pop(struct sk_buff *skb)
|
|
{
|
|
struct nshhdr *nh;
|
|
size_t length;
|
|
__be16 inner_proto;
|
|
|
|
if (!pskb_may_pull(skb, NSH_BASE_HDR_LEN))
|
|
return -ENOMEM;
|
|
nh = (struct nshhdr *)(skb->data);
|
|
length = nsh_hdr_len(nh);
|
|
inner_proto = tun_p_to_eth_p(nh->np);
|
|
if (!pskb_may_pull(skb, length))
|
|
return -ENOMEM;
|
|
|
|
if (!inner_proto)
|
|
return -EAFNOSUPPORT;
|
|
|
|
skb_pull_rcsum(skb, length);
|
|
skb_reset_mac_header(skb);
|
|
skb_reset_network_header(skb);
|
|
skb_reset_mac_len(skb);
|
|
skb->protocol = inner_proto;
|
|
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL_GPL(nsh_pop);
|
|
|
|
static struct sk_buff *nsh_gso_segment(struct sk_buff *skb,
|
|
netdev_features_t features)
|
|
{
|
|
struct sk_buff *segs = ERR_PTR(-EINVAL);
|
|
unsigned int nsh_len, mac_len;
|
|
__be16 proto;
|
|
int nhoff;
|
|
|
|
skb_reset_network_header(skb);
|
|
|
|
nhoff = skb->network_header - skb->mac_header;
|
|
mac_len = skb->mac_len;
|
|
|
|
if (unlikely(!pskb_may_pull(skb, NSH_BASE_HDR_LEN)))
|
|
goto out;
|
|
nsh_len = nsh_hdr_len(nsh_hdr(skb));
|
|
if (unlikely(!pskb_may_pull(skb, nsh_len)))
|
|
goto out;
|
|
|
|
proto = tun_p_to_eth_p(nsh_hdr(skb)->np);
|
|
if (!proto)
|
|
goto out;
|
|
|
|
__skb_pull(skb, nsh_len);
|
|
|
|
skb_reset_mac_header(skb);
|
|
skb_reset_mac_len(skb);
|
|
skb->protocol = proto;
|
|
|
|
features &= NETIF_F_SG;
|
|
segs = skb_mac_gso_segment(skb, features);
|
|
if (IS_ERR_OR_NULL(segs)) {
|
|
skb_gso_error_unwind(skb, htons(ETH_P_NSH), nsh_len,
|
|
skb->network_header - nhoff,
|
|
mac_len);
|
|
goto out;
|
|
}
|
|
|
|
for (skb = segs; skb; skb = skb->next) {
|
|
skb->protocol = htons(ETH_P_NSH);
|
|
__skb_push(skb, nsh_len);
|
|
skb_set_mac_header(skb, -nhoff);
|
|
skb->network_header = skb->mac_header + mac_len;
|
|
skb->mac_len = mac_len;
|
|
}
|
|
|
|
out:
|
|
return segs;
|
|
}
|
|
|
|
static struct packet_offload nsh_packet_offload __read_mostly = {
|
|
.type = htons(ETH_P_NSH),
|
|
.priority = 15,
|
|
.callbacks = {
|
|
.gso_segment = nsh_gso_segment,
|
|
},
|
|
};
|
|
|
|
static int __init nsh_init_module(void)
|
|
{
|
|
dev_add_offload(&nsh_packet_offload);
|
|
return 0;
|
|
}
|
|
|
|
static void __exit nsh_cleanup_module(void)
|
|
{
|
|
dev_remove_offload(&nsh_packet_offload);
|
|
}
|
|
|
|
module_init(nsh_init_module);
|
|
module_exit(nsh_cleanup_module);
|
|
|
|
MODULE_AUTHOR("Jiri Benc <jbenc@redhat.com>");
|
|
MODULE_DESCRIPTION("NSH protocol");
|
|
MODULE_LICENSE("GPL v2");
|