10 Star 18 Fork 52

openEuler/opensource-intern

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
nsh.rst 5.96 KB
一键复制 编辑 原始数据 按行查看 历史

nsh

nsh.c (Network Service Header)

Function Description

The nsh.c file implements the Network Service Header (NSH) protocol, which is part of the Service Function Chaining (SFC) framework. The file includes functions for adding and removing NSH headers and handling Generic Segmentation Offload (GSO) for NSH packets.

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;
    }
    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;
}
  • `nsh_push` function: This function is responsible for adding an NSH header to the packet. - It calculates the length of the NSH header to be added. - Determines the next protocol type based on whether there is a MAC layer length. - Ensures there is enough space to insert the NSH header using skb_cow_head. - Copies the NSH header information into the packet and updates the relevant protocol fields and pointers. - Sets the packet's protocol field to ETH_P_NSH and resets the MAC and network header pointers.
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);
    if (length < NSH_BASE_HDR_LEN)
        return -EINVAL;
    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;
}
  • `nsh_pop` function: This function removes the NSH header from the packet. - Verifies that the packet contains the complete NSH base header length. - Calculates the total length of the NSH header. - Checks if the NSH header length is valid. - Retrieves the inner protocol type and verifies its validity. - Removes the NSH header and restores the original state of the packet, including updating the protocol field and other related pointers.
static struct sk_buff *nsh_gso_segment(struct sk_buff *skb, netdev_features_t features)
{
    unsigned int outer_hlen, mac_len, nsh_len;
    struct sk_buff *segs = ERR_PTR(-EINVAL);
    u16 mac_offset = skb->mac_header;
    __be16 outer_proto, proto;
    skb_reset_network_header(skb);
    outer_proto = skb->protocol;
    outer_hlen = skb_mac_header_len(skb);
    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 (nsh_len < NSH_BASE_HDR_LEN)
        goto out;
    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->mac_len = proto == htons(ETH_P_TEB) ? ETH_HLEN : 0;
    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,
                             mac_offset, mac_len);
        goto out;
    }
    for (skb = segs; skb; skb = skb->next) {
        skb->protocol = outer_proto;
        __skb_push(skb, nsh_len + outer_hlen);
        skb_reset_mac_header(skb);
        skb_set_network_header(skb, outer_hlen);
        skb->mac_len = mac_len;
    }
out:
    return segs;
}
  • `nsh_gso_segment` function: This function handles GSO segmentation for NSH packets. - Resets the network header pointer. - Retrieves the outer protocol type and related lengths. - Checks if there is enough data to contain the complete NSH base header. - Calculates the total length of the NSH header and verifies its validity. - Retrieves the inner protocol type and verifies its validity. - Removes the NSH header and updates the packet's relevant information. - Calls skb_mac_gso_segment to perform GSO segmentation. - If segmentation fails, it unwinds the operation. - Restores the NSH header and related pointers for each segment.

Open Capabilities

  • Custom Header Creation: Developers can extend the nsh_push and nsh_pop functions to customize the construction and parsing logic of the NSH header.
  • GSO Segmentation Control: By implementing or modifying the nsh_gso_segment function, developers can adjust the GSO segmentation behavior for NSH packets as needed.
  • Error Handling: In the nsh_push and nsh_pop functions, developers can customize error handling logic, such as returning specific error codes or taking other actions.
  • Module Initialization Configuration: In the nsh_init_module function, developers can customize the initial setup of the NSH module, such as registering offload handlers.
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/openeuler/opensource-intern.git
[email protected]:openeuler/opensource-intern.git
openeuler
opensource-intern
opensource-intern
master

搜索帮助