struct skb_buff和struct sk_buff关系
时间: 2023-12-14 11:04:57 浏览: 74
`struct sk_buff`是Linux内核网络协议栈中的一个数据结构,代表了一个网络数据包。
`struct skb_buff`是`struct sk_buff`的一个别名,在Linux内核源代码中经常被使用。这个别名是为了简化代码,让代码更易读。
因此,`struct skb_buff`和`struct sk_buff`是同一个数据结构,只是名称不同而已。在Linux内核源代码中,两个名称可以互换使用。
相关问题
将下面这段代码转化成MIPS汇编指令void skb_insert(struct sk_buff *old, struct sk_buff *newsk, struct sk_buff_head *list); static inline void __skb_insert(struct sk_buff *newsk, struct sk_buff *prev, struct sk_buff *next, struct sk_buff_head *list) { newsk->next = next; newsk->prev = prev; next->prev = prev->next = newsk; list->qlen++; }
以下是将该段代码转化成MIPS汇编指令的过程:
```
skb_insert:
addi $sp, $sp, -16 # 为保存寄存器分配16字节的栈空间
sw $ra, 12($sp) # 保存返回地址
sw $s0, 8($sp) # 保存$s0寄存器
sw $s1, 4($sp) # 保存$s1寄存器
move $s0, $a0 # 将old保存到$s0
move $s1, $a1 # 将newsk保存到$s1
lw $t0, 12($a2) # 将list->next保存到$t0
lw $t1, 8($s1) # 将newsk->prev保存到$t1
lw $t2, 4($s1) # 将newsk->next保存到$t2
sw $a2, 0($sp) # 保存list指针到栈空间
jal __skb_insert # 调用__skb_insert函数
lw $ra, 12($sp) # 恢复返回地址
lw $s0, 8($sp) # 恢复$s0寄存器
lw $s1, 4($sp) # 恢复$s1寄存器
addi $sp, $sp, 16 # 释放栈空间
jr $ra # 返回
__skb_insert:
addi $sp, $sp, -16 # 为保存寄存器分配16字节的栈空间
sw $ra, 12($sp) # 保存返回地址
sw $s0, 8($sp) # 保存$s0寄存器
sw $s1, 4($sp) # 保存$s1寄存器
sw $s2, 0($sp) # 保存$s2寄存器
move $s0, $a0 # 将newsk保存到$s0
move $s1, $a1 # 将prev保存到$s1
move $s2, $a2 # 将next保存到$s2
sw $zero, 0($s0) # newsk->next = NULL
sw $s1, 4($s0) # newsk->prev = prev
sw $s2, 0($s0) # newsk->next = next
sw $s0, 4($s1) # prev->next = newsk
sw $s0, 0($s2) # next->prev = newsk
lw $t0, 0($sp) # 将list指针从栈空间中恢复到$t0
lw $t1, ($t0) # 将list->qlen保存到$t1
addi $t1, $t1, 1 # list->qlen++
sw $t1, ($t0) # 将list->qlen保存回list
lw $ra, 12($sp) # 恢复返回地址
lw $s0, 8($sp) # 恢复$s0寄存器
lw $s1, 4($sp) # 恢复$s1寄存器
lw $s2, 0($sp) # 恢复$s2寄存器
addi $sp, $sp, 16 # 释放栈空间
jr $ra # 返回
```
其中,`skb_insert`函数将`old`、`newsk`和`list`分别保存到`s0`、`s1`和`s2`寄存器中,然后将`list`指针保存到栈空间中,并调用`__skb_insert`函数。`__skb_insert`函数将`s0`、`s1`和`s2`分别保存到`newsk`、`prev`和`next`寄存器中,然后按照`__skb_insert`函数中的C代码逐行转化为汇编指令。最后再从栈空间中恢复`list`指针,并将`list->qlen`加1,最后释放栈空间并返回。
static void skb_prepare(struct sk_buff *new_skb, struct sk_buff *old_skb, struct dst_entry *dst, int protocol) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(5,4,0) nf_reset_ct(new_skb); #else nf_reset(new_skb); #endif new_skb->mark = 0; nf_ct_attach( new_skb, old_skb ); new_skb->pkt_type = PACKET_OTHERHOST; new_skb->protocol = htons( protocol ); new_skb->ip_summed = CHECKSUM_NONE; new_skb->priority = 0; skb_dst_set(new_skb, dst); skb_reserve(new_skb, TPLOGIN_ETH_HDR_LEN); return; } 这段代码的功能
这段代码定义了一个名为skb_prepare的静态函数,该函数接受四个参数:new_skb,old_skb,dst和protocol。函数的主要功能是准备一个新的sk_buff用于网络数据包的传输。
具体来说,该函数会首先根据当前内核版本调用nf_reset_ct或nf_reset函数来重置新sk_buff的网络连接跟踪状态。然后将新的sk_buff的标记mark设置为0,将旧的sk_buff绑定到新的sk_buff上,将新的sk_buff的pkt_type设置为PACKET_OTHERHOST,将协议类型protocol设置为新的sk_buff的protocol,将新的sk_buff的校验和类型ip_summed设置为CHECKSUM_NONE,将新的sk_buff的优先级priority设置为0,并设置新的sk_buff的目标路由dst。最后,函数会为新的sk_buff保留TPLOGIN_ETH_HDR_LEN字节的空间来存放以太网头部,然后返回。
阅读全文