JJJ:桥接转发的代码是如何在接收流程中完成转发的

本文解析了Linux内核中的netdev_rx_handler_register函数,用于为网络设备注册接收处理程序,以及__netif_receive_skb及其相关函数如何调用接收处理程序。
br_add_if -》 err = netdev_rx_handler_register(dev, br_handle_frame, p);


4691 /**
4692  *  netdev_rx_handler_register - register receive handler
4693  *  @dev: device to register a handler for
4694  *  @rx_handler: receive handler to register
4695  *  @rx_handler_data: data pointer that is used by rx handler
4696  *
4697  *  Register a receive handler for a device. This handler will then be
4698  *  called from __netif_receive_skb. A negative errno code is returned
4699  *  on a failure.
4700  *
4701  *  The caller must hold the rtnl_mutex.
4702  *
4703  *  For a general description of rx_handler, see enum rx_handler_result.
4704  */
4705 int netdev_rx_handler_register(struct net_device *dev,
4706                    rx_handler_func_t *rx_handler, //此hook会在 __netif_receive_skb 中被调用
4707                    void *rx_handler_data)
4708 {
4709     if (netdev_is_rx_handler_busy(dev))
4710         return -EBUSY;
4711
4712     if (dev->priv_flags & IFF_NO_RX_HANDLER)
4713         return -EINVAL;
4714
4715     /* Note: rx_handler_data must be set before rx_handler */
4716     rcu_assign_pointer(dev->rx_handler_data, rx_handler_data);
4717     rcu_assign_pointer(dev->rx_handler, rx_handler);
4718
4719     return 0;
4720 }




5055 static int __netif_receive_skb(struct sk_buff *skb)
5056 {
5057     int ret;
5058
5059     if (sk_memalloc_socks() && skb_pfmemalloc(skb)) {
5060         unsigned int noreclaim_flag;
5061
5062         /*
5063          * PFMEMALLOC skbs are special, they should
5064          * - be delivered to SOCK_MEMALLOC sockets only
5065          * - stay away from userspace
5066          * - have bounded memory usage
5067          *
5068          * Use PF_MEMALLOC as this saves us from propagating the allocation
5069          * context down to all allocation sites.
5070          */
5071         noreclaim_flag = memalloc_noreclaim_save();
5072         ret = __netif_receive_skb_one_core(skb, true);
5073         memalloc_noreclaim_restore(noreclaim_flag);
5074     } else
5075         ret = __netif_receive_skb_one_core(skb, false);
5076
5077     return ret;
5078 }




4955 static int __netif_receive_skb_one_core(struct sk_buff *skb, bool pfmemalloc)
4956 {
4957     struct net_device *orig_dev = skb->dev;
4958     struct packet_type *pt_prev = NULL;
4959     int ret;
4960
4961     ret = __netif_receive_skb_core(&skb, pfmemalloc, &pt_prev);
4962     if (pt_prev)
4963         ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
4964     return ret;
4965 }




__netif_receive_skb_core中相关的代码片段如下:
4879     rx_handler = rcu_dereference(skb->dev->rx_handler);
4880     if (rx_handler) {
4881         if (pt_prev) {
4882             ret = deliver_skb(skb, pt_prev, orig_dev);
4883             pt_prev = NULL;
4884         }
4885         switch (rx_handler(&skb)) {

<think>首先,用户的问题是:“我想查找解决 '/bin/sh: ./jjj: Permission denied' 错误的方法”,具体是如何解决这个权限被拒绝的错误的错误。 系统的指令包括: - 所有行内数学表达式必须用 $...$ 格式,但这个问题没有数学内容,所以可能不需要。 - 独立公式用 $$...$$,但这里没有公式。 - LaTeX 语法正确:在回复中,如果有数学内容,要遵守,但这里可能没有。 - 使用中文回答:整个回复要用中文。 - 生成相关问题:在回答结束时,生成几个相关问题。 - 引用的段落末尾添加引用标识:如 [^1],但用户提供了引用 [1],是关于其他权限问题的,我需要参考它。 用户提供的引用 [1] 是关于另一个权限错误的:"Permission denied" 错误,用户提到了如何解决。引用内容描述了在脚本执行过程中出现的权限问题,并建议使用 chmod 命令来解决。 用户的问题是关于 "./jjj: Permission denied" 的错误,这与引用中的错误类似。 我的回答结构应该清晰,帮助用户逐步解决问题。确保回答真实可靠。 步骤: 1. **理解错误**:解释这个错误意味着什么。错误消息 "/bin/sh: ./jjj: Permission denied" 表明当尝试运行脚本或文件 "./jjj" 时,shell 没有执行权限。 2. **解决方法**:建议使用 chmod 命令来添加执行权限。 - 例如:运行 `chmod +x jjj` 来添加执行权限。 - 确保文件存在,并且用户有权限修改它。 3. **参考提供的引用**:引用 [1] 提到使用 chmod 来解决类似的权限问题,所以我可以在回答中引用它。 - 在相关部分末尾添加引用标识,如 [^1]。 4. **预防措施**:解释如何避免类似问题,比如在创建脚本时设置权限。 5. **生成相关问题**:在回答结束时,添加几个相关问题,类似于示例中的格式。 生成的回答结构: - 开头:确认问题并解释错误。 - 主体:逐步说明解决方法。 - 结束:生成相关问题。 相关问题示例: 1. 如何检查文件权限? 2. 如何永久设置文件权限? 3. 其他常见的权限错误及其解决方法? 确保回答完整: - 错误原因:文件没有可执行权限。 - 解决步骤: 1. 检查文件是否存在:`ls -l jjj` 2. 添加执行权限:`chmod +x jjj` 3. 尝试再次运行:`./jjj` - 如果问题依旧,考虑其他可能性,如文件所有权或路径问题。 参考用户的引用: - 在回答中,提到类似问题可以用 chmod 解决,并添加引用 [^1]。 最终回答用中文。 完整回答大纲: 1. 介绍错误:这个错误表示尝试执行的脚本或文件没有足够的权限。 2. 解决方法: - 使用 chmod 命令添加执行权限。 - 示例命令:`chmod +x jjj` - 解释:这将使文件可执行。 - 参考引用:类似问题可以通过 chmod 解决 [^1]。 3. 额外建议:检查文件类型、所有权等。 4. 生成相关问题。 </think>### 解决 '/bin/sh: ./jjj: Permission denied' 错误的方法 此错误表示您尝试执行文件 `./jjj` 时,系统拒绝了权限,通常是因为该文件缺少可执行权限(execute permission)。以下是系统性的解决步骤,基于 Linux/Unix 环境中的常见实践(确保您有管理员或文件所有者权限)。参考类似权限问题的处理方式[^1]。 #### 逐步解决方法 1. **检查文件权限与所有权**: - 使用 `ls -l` 命令查看文件详细信息: ```bash ls -l jjj ``` - 输出示例:`-rw-r--r-- 1 user group 1024 Jan 1 12:00 jjj`(表示没有 `x` 权限)。 - 如果所有者不正确,使用 `chown` 修改所有权(例如:`sudo chown your_username jjj`)。 2. **添加可执行权限**: - 运行 `chmod` 命令为文件添加执行权限: ```bash chmod +x jjj ``` - 这会将权限更改为类似 `-rwxr-xr-x`,允许执行。 - 如果文件在特定路径下,确保命令路径正确(如 `chmod +x /path/to/jjj`)。 - 验证权限是否生效:再次运行 `ls -l jjj`。 3. **尝试重新执行文件**: - 运行文件: ```bash ./jjj ``` - 如果错误消失,表示问题已解决。 4. **检查文件类型与完整性**: - 确保 `jjj` 是可执行文件(如脚本或二进制程序),使用 `file jjj` 检查类型(例如:是否标记为 `Bourne-Again shell script`)。 - 如果文件损坏或不完整,重新下载或创建备份。 #### 常见问题排查 - **权限不足**:如果您不是文件所有者,需要在 `chmod` 前加 `sudo`(例如:`sudo chmod +x jjj`)。 - **路径问题**:确保当前目录包含 `jjj` 文件(使用 `pwd` 确认路径)。 - **SELinux/AppArmor 限制**:在某些系统(如 CentOS),安全模块可能阻止执行;临时禁用或调整策略(需谨慎)。 - 类似错误可通过 `chmod` 修复,如引用中所述的处理方式[^1]。 #### 预防措施 - 创建新脚本时,直接设置权限:`chmod +x filename.sh`。 - 使用 `umask` 配置默认权限(例如:`umask 022` 确保新文件可执行)。 如果上述步骤无效,请提供更多细节(如操作系统类型或文件来源),以便进一步诊断。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值