邻居表项的unres_qlen_bytes长度

2023-12-19 09:39

本文主要是介绍邻居表项的unres_qlen_bytes长度,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

对于每个未解析的邻居地址,变量unres_qlen和unres_qlen_bytes分别控制可换成的报文数量和报文字节数量,其中前者unres_qlen在内核linux-3.3版本已经废弃,应使用后一个变量unres_qlen_bytes,其默认值为SK_WMEM_MAX(即net.core.wmem_default),内核建议此值的设置应能够容纳256个中型长度的报文。

通过PROC文件unres_qlen和unres_qlen_bytes可查看和修改其值。

$ cat /proc/sys/net/ipv4/neigh/ens33/unres_qlen
101
$ cat /proc/sys/net/ipv4/neigh/ens33/unres_qlen_bytes 
212992

在arp邻居表arp_tbl中将NEIGH_VAR_QUEUE_LEN_BYTES索引所对应的表项(unres_qlen_bytes)初始化为SK_WMEM_MAX。

struct neigh_table arp_tbl = {.family     = AF_INET,.key_len    = 4,.protocol   = cpu_to_be16(ETH_P_IP),.hash       = arp_hash,.key_eq     = arp_key_eq,.constructor    = arp_constructor,.proxy_redo = parp_redo,.id     = "arp_cache",.parms      = {.tbl            = &arp_tbl,.reachable_time     = 30 * HZ,.data   = {[NEIGH_VAR_QUEUE_LEN_BYTES] = SK_WMEM_MAX,[NEIGH_VAR_PROXY_QLEN] = 64,

内核中静态变量neigh_sysctl_table定义了unres_qlen_bytes和unres_qlen的PROC文件信息。注意这里的参数QUEUE_LEN_BYTES,其实际上为NEIGH_VAR_QUEUE_LEN_BYTES,两者使用的是相同的,即指向同一个变量,只是在显示时unres_qlen需要进行转换。

static struct neigh_sysctl_table {struct ctl_table_header *sysctl_header;struct ctl_table neigh_vars[NEIGH_VAR_MAX + 1];
} neigh_sysctl_template __read_mostly = {.neigh_vars = {...NEIGH_SYSCTL_ZERO_INTMAX_ENTRY(QUEUE_LEN_BYTES, "unres_qlen_bytes"),...NEIGH_SYSCTL_UNRES_QLEN_REUSED_ENTRY(QUEUE_LEN, QUEUE_LEN_BYTES, "unres_qlen"),

如下unres_qlen的转换函数proc_unres_qlen,对于读操作,需要将unres_qlen_bytes的值除以SKB_TRUESIZE(ETH_FRAME_LEN)的值,以得到unres_qlen的值。而对于写操作需进行相反的操作,将设置的unres_qlen乘以SKB_TRUESIZE(ETH_FRAME_LEN)的值。

unres_qlen_max限定了unres_qlen的最大值。

static int int_max = INT_MAX;
static int unres_qlen_max = INT_MAX / SKB_TRUESIZE(ETH_FRAME_LEN);static int proc_unres_qlen(struct ctl_table *ctl, int write,void __user *buffer, size_t *lenp, loff_t *ppos)
{int size, ret;struct ctl_table tmp = *ctl;tmp.extra1 = &zero;tmp.extra2 = &unres_qlen_max;tmp.data = &size;size = *(int *)ctl->data / SKB_TRUESIZE(ETH_FRAME_LEN);ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);if (write && !ret)*(int *)ctl->data = size * SKB_TRUESIZE(ETH_FRAME_LEN);return ret;

netlink接口

通过netlink设置unres_qlen和unres_qlen_bytes的值由以下函数neightbl_set处理,注意对于NDTPA_QUEUE_LEN,需要先行将其转换为字节数进行设置,两者设置的都是同一个变量,即NEIGH_VAR_QUEUE_LEN_BYTES为索引的数组成员。

static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh, struct netlink_ext_ack *extack)
{struct neigh_table *tbl;struct nlattr *tb[NDTA_MAX+1];if (tb[NDTA_PARMS]) {struct neigh_parms *p;p = lookup_neigh_parms(tbl, net, ifindex);...for (i = 1; i <= NDTPA_MAX; i++) {if (tbp[i] == NULL) continue;switch (i) {...case NDTPA_QUEUE_LEN:NEIGH_VAR_SET(p, QUEUE_LEN_BYTES,nla_get_u32(tbp[i]) * SKB_TRUESIZE(ETH_FRAME_LEN));break;case NDTPA_QUEUE_LENBYTES:NEIGH_VAR_SET(p, QUEUE_LEN_BYTES, nla_get_u32(tbp[i]));break;

以下函数neightbl_fill_parms读取内核中的unres_qlen和unres_qlen_bytes的值,其中前者为一个近似值。

static int neightbl_fill_parms(struct sk_buff *skb, struct neigh_parms *parms)
{struct nlattr *nest;nest = nla_nest_start(skb, NDTA_PARMS);if (nest == NULL)return -ENOBUFS;if ((parms->dev &&nla_put_u32(skb, NDTPA_QUEUE_LENBYTES,NEIGH_VAR(parms, QUEUE_LEN_BYTES)) ||/* approximative value for deprecated QUEUE_LEN (in packets) */nla_put_u32(skb, NDTPA_QUEUE_LEN,NEIGH_VAR(parms, QUEUE_LEN_BYTES) / SKB_TRUESIZE(ETH_FRAME_LEN)) ||

unres_qlen处理

变量unres_qlen的值在数据流程中用到,如下函数__neigh_event_send,如果邻居表项的状态位没有设置NUD_STALE和NUD_INCOMPLETE,并且探测次数不为零,立即开始地址探测(immediate_probe)。并且,将邻居表项的状态位图设置为NUD_INCOMPLETE。

int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
{int rc;bool immediate_probe = false;...if (neigh->nud_state & (NUD_CONNECTED | NUD_DELAY | NUD_PROBE))goto out_unlock_bh;if (neigh->dead)goto out_dead;if (!(neigh->nud_state & (NUD_STALE | NUD_INCOMPLETE))) {if (NEIGH_VAR(neigh->parms, MCAST_PROBES) +NEIGH_VAR(neigh->parms, APP_PROBES)) {unsigned long next, now = jiffies;atomic_set(&neigh->probes, NEIGH_VAR(neigh->parms, UCAST_PROBES));neigh->nud_state     = NUD_INCOMPLETE;neigh->updated = now;next = now + max(NEIGH_VAR(neigh->parms, RETRANS_TIME), HZ/2);neigh_add_timer(neigh, next);immediate_probe = true;} else {neigh->nud_state = NUD_FAILED;...kfree_skb(skb);return 1;}} else if (neigh->nud_state & NUD_STALE) {...}

如果在发送报文时,邻居地址的状态等于NUD_INCOMPLETE,并且arp_queue队列中的报文总长度arp_queue_len_bytes与当前发送报文的长度(skb->truesize)之和,大于限定的QUEUE_LEN_BYTES值,将arp_queue队列中头部(最老的)报文释放,之后,再次检测总长度是否超限。

最终,将当前报文添加到arp_queue队列的尾部,同时增加缓存报文的总长度arp_queue_len_bytes。

    if (neigh->nud_state == NUD_INCOMPLETE) {if (skb) {while (neigh->arp_queue_len_bytes + skb->truesize >NEIGH_VAR(neigh->parms, QUEUE_LEN_BYTES)) {struct sk_buff *buff;buff = __skb_dequeue(&neigh->arp_queue);if (!buff)break;neigh->arp_queue_len_bytes -= buff->truesize;kfree_skb(buff);NEIGH_CACHE_STAT_INC(neigh->tbl, unres_discards);}skb_dst_force(skb);__skb_queue_tail(&neigh->arp_queue, skb);neigh->arp_queue_len_bytes += skb->truesize;}rc = 1;}
out_unlock_bh:if (immediate_probe)neigh_probe(neigh);

内核版本 5.0

这篇关于邻居表项的unres_qlen_bytes长度的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/511723

相关文章

bytes.split的用法和注意事项

当然,我很乐意详细介绍 bytes.Split 的用法和注意事项。这个函数是 Go 标准库中 bytes 包的一个重要组成部分,用于分割字节切片。 基本用法 bytes.Split 的函数签名如下: func Split(s, sep []byte) [][]byte s 是要分割的字节切片sep 是用作分隔符的字节切片返回值是一个二维字节切片,包含分割后的结果 基本使用示例: pa

Java应用对接pinpoint监控工具的时候,应用名称长度超出限制而导致接入失败

一、背景 java应用需要接入pinpoint,同一个虚拟机上的其他应用接入成功,唯独本应用不行。 首先排除是pinpoint agent的问题,因为其他应用都正常。 然后,我就对比二者的启动脚本。 -javaagent:/opt/pinpoint/pinpoint-bootstrap.jar -Dpinpoint.agentId=DA301004_17 -Dpinpoint.applic

2300年都无人能知有长度不同的伪≌射线

黄小宁 【摘要】自有射线概念后的2300年里一直无人能知有长度不同的射线。保距变换和≌图概念是能放大无穷大倍的思维望远镜使人能一下子看到有长度不同的伪重合、伪≌射线。 变量x所取各数也均由x代表,x代表其变域(x所有能取的数组成的集)内任一元。设集A={x}表A各元均由x代表,{x}中变量x的变域是A。其余类推。“实数集”R所有非负元x≥0组成R+={x≥0},这里的x≥0不是表示x可取一切非负

MQTT协议中信息长度MSG len字段分析

截图自: 主要是说数据字节长度的计算: 每个字节由1个持续位和7个数据位组成:如果持续位为1,表示接下来的一个字节仍然表示长度的一部分 7个数据位表示的数据     0-127   共计128个数字 所以如上图的表格所示 1个字节,2个字节,3个字节,4个字节的数据范围 切记:MQTT长度的表示范围 最多使用4个字节  故这里存在着数据长度的限制  (不过真心牛掰! 试试Q

EL表达式获取List集合长度

有一次在jsp页面我要获取后台的一个list集合的长度,当然你可以在后台保存长度然后在页面获取,这是一种方法,现在我介绍另一种方法: 首先:我们在jsp页面导入jstl标签库<%@ taglib prefix="fn" uri="http://java.sun.com/jsp.jstl/functions"%> 然后在你要获取的地方写上:${fn:length(qunarRemarkList)

mysql数据库中的字符串长度函数:LENGTH() 与 CHAR_LENGTH()

在数据库管理系统中,处理字符串数据时,了解字符串的长度是一个常见且重要的需求。无论是为了数据验证、格式化输出,还是在进行复杂的查询操作中,准确获取字符串的长度都是必不可少的。SQL标准提供了几种函数来帮助我们实现这一目标,其中LENGTH()和CHAR_LENGTH()是两个常被提及的函数,尽管它们在某些数据库系统中可能表现出相似的行为,但在一些细节上存在差异。本文将深入探讨这两个函数的用法及其区

计算两个字符串的最大公共字符串的长度,字符不区分大小写

/*** */package testString;import java.util.Scanner;/***@author: Administrator*@date: 2016-12-28 下午01:08:30*/public class Main {public static void main(String[] args){Scanner sc=new Scanner(Syste

【滑动窗口】| 力扣高频题: 长度最小的数组

🎗️ 主页:小夜时雨 🎗️专栏:算法题 🎗️如何活着,是我找寻的方向 目录 1. 题目解析2. 代码 1. 题目解析 题目链接: https://leetcode.cn/problems/minimum-size-subarray-sum/description/ (可点击) 本道题是滑动窗口的一道经典应用问题:找出数组中长度最小的子数组。 滑动窗口优化思

力扣209:长度最小的数组

给定一个含有 n 个正整数的数组和一个正整数 target 。找出该数组中满足其总和大于等于 target 的长度最小的 子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。 示例 1: 输入:target = 7, nums = [2,3,1,2,4,3]输出:2解释:子数组 [4,3] 是该条件

【C】单词长度

课程:程序设计入门——C语言(翁恺) 题目内容: 你的程序要读入一行文本,其中以空格分隔为若干个单词,以‘.’结束。你要输出这行文本中每个单词的长度。这里的单词与语言无关,可以包括各种符号,比如“it's”算一个单词,长度为4。注意,行中可能出现连续的空格。 输入格式: 输入在一行中给出一行文本,以‘.’结束,结尾的句号不能计算在最后一个单词的长度内。 输出格式: 在一行中输出这行