ifconfig创建sit隧道

2023-12-19 09:32
文章标签 创建 ifconfig 隧道 sit

本文主要是介绍ifconfig创建sit隧道,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

通常可使用ip命令创建sit隧道设备,如下:

# ip tunnel add sit1 mode sit remote 192.168.20.1 local 192.168.20.5
#
# ip link
5: sit0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN mode DEFAULT group default qlen 1000link/sit 0.0.0.0 brd 0.0.0.0
6: sit1@NONE: <POINTOPOINT,NOARP> mtu 1480 qdisc noop state DOWN mode DEFAULT group default qlen 1000link/sit 192.168.20.5 peer 192.168.20.1

也可使用ifconfig命令创建sit隧道,虽然ifconfig命令报错,但是仍然创建了新的sit2隧道设备。如下可见,此ifconfig不能指定新创建设备的名称,并且不能指定隧道的本端地址。

新创建的sit2设备与ifconfig命令参数sit0没有关联关系,二者只是在同一命名空间。

# ifconfig sit0 tunnel ::192.168.10.1             
SIOCSIFDSTADDR: No buffer space available
#
# ip link
7: sit2@NONE: <POINTOPOINT,NOARP> mtu 1480 qdisc noop state DOWN mode DEFAULT group default qlen 1000link/sit 0.0.0.0 peer 192.168.10.1
#
$ ip tunnel
sit0: ipv6/ip remote any local any ttl 64 nopmtudisc 6rd-prefix 2002::/16
sit1: ipv6/ip remote 192.168.20.1 local 192.168.20.5 ttl inherit 6rd-prefix 2002::/16
sit2: ipv6/ip remote 192.168.10.1 local any ttl 64 6rd-prefix 2002::/16

ifconfig子命令tunnel使用ioctl控制字SIOCSIFDSTADDR将数据下发到内核中,由函数inet6_ioctl处理。

int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{   void __user *argp = (void __user *)arg;struct sock *sk = sock->sk;struct net *net = sock_net(sk);switch (cmd) {case SIOCSIFDSTADDR:return addrconf_set_dstaddr(net, argp);

如下addrconf_set_dstaddr函数,ifconfig参数中的设备(sit0)要求必须是ARPHRD_SIT。

/**  Set destination address.*  Special case for SIT interfaces where we create a new "virtual" device.*/
int addrconf_set_dstaddr(struct net *net, void __user *arg)
{struct net_device *dev;struct in6_ifreq ireq;int err = -ENODEV;if (!IS_ENABLED(CONFIG_IPV6_SIT))return -ENODEV;if (copy_from_user(&ireq, arg, sizeof(struct in6_ifreq)))return -EFAULT;rtnl_lock();dev = __dev_get_by_index(net, ireq.ifr6_ifindex);if (dev && dev->type == ARPHRD_SIT)err = addrconf_set_sit_dstaddr(net, dev, &ireq);rtnl_unlock();return err;

隧道参数仅设置了目的地址daddr、版本version、IP头部长度ihl、协议(41)和TTL值64。ndo_tunnel_ctl执行隧道添加操作,之后,根据返回的隧道名称查找设备,出错的话返回ENOBUFS,即以上看到的ifconfig错误(稍后说明),但是隧道已经创建完成。只是没有执行dev_open,隧道是down的状态。

ifconfig配置的远端地址必须是兼容IPv4的IPv6地址,从其中可取出IPv4地址。

static int addrconf_set_sit_dstaddr(struct net *net, struct net_device *dev, struct in6_ifreq *ireq)
{struct ip_tunnel_parm p = { };if (!(ipv6_addr_type(&ireq->ifr6_addr) & IPV6_ADDR_COMPATv4))return -EADDRNOTAVAIL;p.iph.daddr = ireq->ifr6_addr.s6_addr32[3];p.iph.version = 4;p.iph.ihl = 5;p.iph.protocol = IPPROTO_IPV6;p.iph.ttl = 64;if (!dev->netdev_ops->ndo_tunnel_ctl)return -EOPNOTSUPP;err = dev->netdev_ops->ndo_tunnel_ctl(dev, &p, SIOCADDTUNNEL);if (err) return err;dev = __dev_get_by_name(net, p.name);if (!dev)return -ENOBUFS;return dev_open(dev, NULL);

对于sit模块,注册的ioctl命令为ipip6_tunnel_ctl,隧道添加操作由函数ipip6_tunnel_add实现。

static const struct net_device_ops ipip6_netdev_ops = {....ndo_tunnel_ctl = ipip6_tunnel_ctl,
};static int ipip6_tunnel_ctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd)
{switch (cmd) {case SIOCGETTUNNEL:return ipip6_tunnel_get(dev, p);case SIOCADDTUNNEL:return ipip6_tunnel_add(dev, p);

函数ipip6_tunnel_locate查找是否存在相同的隧道,为真返回已有隧道结构,否则,创建一个新的隧道。如果创建失败,也是返回错误ENOBUFS。

static int ipip6_tunnel_add(struct net_device *dev, struct ip_tunnel_parm *p)
{struct ip_tunnel *t = netdev_priv(dev);err = __ipip6_tunnel_ioctl_validate(t->net, p);if (err)return err;t = ipip6_tunnel_locate(t->net, p, 1);if (!t)return -ENOBUFS;return 0;

由于ifconfig配置时没有指定隧道名称,所以parms->name为空,使用系统自动分配的名称"sit%d",在注册隧道设备注册完成之后,才会有完整的名称。但是,函数最后没有更新parms->name的值,其仍然为空。

所以,在以上函数addrconf_set_sit_dstaddr中,根据parms->name来查找设备,必定找不到。

static struct ip_tunnel *ipip6_tunnel_locate(struct net *net,struct ip_tunnel_parm *parms, int create)
{...if (parms->name[0]) {if (!dev_valid_name(parms->name))goto failed;strlcpy(name, parms->name, IFNAMSIZ);} else {strcpy(name, "sit%d");}dev = alloc_netdev(sizeof(*t), name, NET_NAME_UNKNOWN, ipip6_tunnel_setup);if (!dev)return NULL;dev_net_set(dev, net);nt = netdev_priv(dev);nt->parms = *parms;if (ipip6_tunnel_create(dev) < 0)goto failed_free;

这种创建sit隧道的方法应该已经过时。

内核版本 5.10

这篇关于ifconfig创建sit隧道的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Window Server2016 AD域的创建的方法步骤

《WindowServer2016AD域的创建的方法步骤》本文主要介绍了WindowServer2016AD域的创建的方法步骤,文中通过图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价... 目录一、准备条件二、在ServerA服务器中常见AD域管理器:三、创建AD域,域地址为“test.ly”

Python在固定文件夹批量创建固定后缀的文件(方法详解)

《Python在固定文件夹批量创建固定后缀的文件(方法详解)》文章讲述了如何使用Python批量创建后缀为.md的文件夹,生成100个,代码中需要修改的路径、前缀和后缀名,并提供了注意事项和代码示例,... 目录1. python需求的任务2. Python代码的实现3. 代码修改的位置4. 运行结果5.

使用IntelliJ IDEA创建简单的Java Web项目完整步骤

《使用IntelliJIDEA创建简单的JavaWeb项目完整步骤》:本文主要介绍如何使用IntelliJIDEA创建一个简单的JavaWeb项目,实现登录、注册和查看用户列表功能,使用Se... 目录前置准备项目功能实现步骤1. 创建项目2. 配置 Tomcat3. 项目文件结构4. 创建数据库和表5.

使用SpringBoot创建一个RESTful API的详细步骤

《使用SpringBoot创建一个RESTfulAPI的详细步骤》使用Java的SpringBoot创建RESTfulAPI可以满足多种开发场景,它提供了快速开发、易于配置、可扩展、可维护的优点,尤... 目录一、创建 Spring Boot 项目二、创建控制器类(Controller Class)三、运行

JAVA中整型数组、字符串数组、整型数和字符串 的创建与转换的方法

《JAVA中整型数组、字符串数组、整型数和字符串的创建与转换的方法》本文介绍了Java中字符串、字符数组和整型数组的创建方法,以及它们之间的转换方法,还详细讲解了字符串中的一些常用方法,如index... 目录一、字符串、字符数组和整型数组的创建1、字符串的创建方法1.1 通过引用字符数组来创建字符串1.2

手把手教你idea中创建一个javaweb(webapp)项目详细图文教程

《手把手教你idea中创建一个javaweb(webapp)项目详细图文教程》:本文主要介绍如何使用IntelliJIDEA创建一个Maven项目,并配置Tomcat服务器进行运行,过程包括创建... 1.启动idea2.创建项目模板点击项目-新建项目-选择maven,显示如下页面输入项目名称,选择

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

在cscode中通过maven创建java项目

在cscode中创建java项目 可以通过博客完成maven的导入 建立maven项目 使用快捷键 Ctrl + Shift + P 建立一个 Maven 项目 1 Ctrl + Shift + P 打开输入框2 输入 "> java create"3 选择 maven4 选择 No Archetype5 输入 域名6 输入项目名称7 建立一个文件目录存放项目,文件名一般为项目名8 确定

Java 创建图形用户界面(GUI)入门指南(Swing库 JFrame 类)概述

概述 基本概念 Java Swing 的架构 Java Swing 是一个为 Java 设计的 GUI 工具包,是 JAVA 基础类的一部分,基于 Java AWT 构建,提供了一系列轻量级、可定制的图形用户界面(GUI)组件。 与 AWT 相比,Swing 提供了许多比 AWT 更好的屏幕显示元素,更加灵活和可定制,具有更好的跨平台性能。 组件和容器 Java Swing 提供了许多

顺序表之创建,判满,插入,输出

文章目录 🍊自我介绍🍊创建一个空的顺序表,为结构体在堆区分配空间🍊插入数据🍊输出数据🍊判断顺序表是否满了,满了返回值1,否则返回0🍊main函数 你的点赞评论就是对博主最大的鼓励 当然喜欢的小伙伴可以:点赞+关注+评论+收藏(一键四连)哦~ 🍊自我介绍   Hello,大家好,我是小珑也要变强(也是小珑),我是易编程·终身成长社群的一名“创始团队·嘉宾”