
从逻辑上说,网络命名空间是网络栈的副本,有自己的网路设备、路由选择表、邻接表、Netfilter表、网络套接字、网络procfs条目、网络sysfs条目和其它网络资源。
网络命名空间可以构建出多个内核网络栈实例的表象。网络命名空间的构架为net,定义在文件include/net/net_namespace.h
struct net {
refcount_t passive; /* To decided when the network
* namespace should be freed.
*/
atomic_t count; /* To decided when the network
* namespace should be shut down.
*/
spinlock_t rules_mod_lock;
atomic64_t cookie_gen;
struct list_head list; /* list of network namespaces */
struct list_head cleanup_list; /*namespaces on death row */
struct list_head exit_list; /* Useonly net_mutex */
struct user_namespace *user_ns; /* Owninguser namespace */
struct ucounts *ucounts;
spinlock_t nsid_lock;
struct idr netns_ids;
struct ns_common ns;
struct proc_dir_entry *proc_net;
struct proc_dir_entry *proc_net_stat;
#ifdef CONFIG_SYSCTL
struct ctl_table_set sysctls;
#endif
struct sock *rtnl; /* rtnetlink socket */
struct sock *genl_sock;
struct list_headdev_base_head;//指向一个包含所有网络设备的数组
struct hlist_head *dev_name_head;//指向一个包含所有网络设备的轮询表,键为网络设备名
struct hlist_head *dev_index_head;//指向一个包含所有网络设备的轮询表,键为网络设备索引
unsignedintdev_base_seq; /* protected by rtnl_mutex */
int ifindex;//网络命名空间中分配的更有一个设备索引
unsignedint dev_unreg_count;
/* core fib_rules */
struct list_head rules_ops;

struct list_head fib_notifier_ops; /*protected by net_mutex */
struct net_device*loopback_dev; /* The loopback */
struct netns_core core;
struct netns_mib mib;
struct netns_packet packet;
struct netns_unix unx;
struct netns_ipv4 ipv4;//是一个netns_ipv4结构示例,用于ipv4子系统
#if IS_ENABLED(CONFIG_IPV6)
struct netns_ipv6 ipv6;
#endif
#if IS_ENABLED(CONFIG_IEEE802154_6LOWPAN)
struct netns_ieee802154_lowpan ieee802154_lowpan;
#endif
#if defined(CONFIG_IP_SCTP) || defined(CONFIG_IP_SCTP_MODULE)
struct netns_sctp sctp;
#endif
#if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE)
struct netns_dccp dccp;
#endif
#ifdef CONFIG_NETFILTER
struct netns_nf nf;
struct netns_xtxt;
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
struct netns_ct ct;
#endif
#if defined(CONFIG_NF_TABLES) || defined(CONFIG_NF_TABLES_MODULE)
struct netns_nftables nft;
#endif
#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
struct netns_nf_frag nf_frag;
#endif
struct sock *nfnl;
struct sock *nfnl_stash;
#if IS_ENABLED(CONFIG_NETFILTER_NETLINK_ACCT)

struct list_head nfnl_acct_list;
#endif
#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
struct list_head nfct_timeout_list;
#endif
#endif
#ifdef CONFIG_WEXT_CORE
struct sk_buff_head wext_nlevents;
#endif
struct net_generic __rcu *gen;
/* Note : following structs are cache line aligned */
#ifdef CONFIG_XFRM
struct netns_xfrm xfrm;//是一个netns_xfrm结构示例,用于IPsec子系统。
#endif
#if IS_ENABLED(CONFIG_IP_VS)
struct netns_ipvs *ipvs;
#endif
#if IS_ENABLED(CONFIG_MPLS)
struct netns_mpls mpls;
#endif
#if IS_ENABLED(CONFIG_CAN)
struct netns_can can;
#endif
struct sock *diag_nlsk;
atomic_t fnhe_genid;
} __randomize_layout;
其中user_ns表示建立网络命名空间的用户命名空间。
proc_inum是网络命名空间独一无二的procinode号.
proc_net表示网络命名空间procfs条目(/proc/net)。每个网络命名空间都维护着自己的procfs条目。
proc_net_stat表示网络命名空间procfs统计信息条目(/proc/net/stat)。每个网络命名空间都维护着自己的profcfs统计条目
结构netns_ipv4包含这些ipv4专用的表和函数,如路由选择表、Netfilter表、组播路由选择表等。
在网络设备对象(net_device)中添加了成员nd_net,是一个指向网络命名空间的指针。这个是通过变量dev_net_set()来设置的
staticinline
void dev_net_set(struct net_device *dev, struct net *net)

{
write_pnet(&dev->nd_net, net);
}
而应获得网络设施相关联的网络命名空间借助dev_net()来完成。
在一个时刻,一个网络设备没法属于一个网络命名空间。
在表示套接字的结构sock中,添加了成员sk_net,是一个指向网络命名空间的指针。
有些网络设施跟网络子系统必须由另类的网络命名空间数据,为了提供这些支持,添加了结构pernet_operations,其包括回调函数init和exit, 用于执行设备初始化和清除工作。在文件include/net/net_namespace.h如下:
struct pernet_operations {
struct list_head list;
int (*init)(struct net *net);
void (*exit)(struct net *net);
void (*exit_batch)(struct list_head *net_exit_list);
unsignedint *id;
size_t size;
};
同时,在组件初始化和被删除时分别调用方式register_pernet_device和unregister_pernet_device,入参为pernet_operations.
在网络命名空间模块定义了一个net_ns_ops对象如下:
staticstruct pernet_operations __net_initdata net_ns_ops = {
.init = net_ns_net_init,
.exit = net_ns_net_exit,
};
位于文件net/core/net_namespace.c中,在开启阶段在net_ns_init函数中注册。
创建新的网络命名空间时,都将读取init回调函数net_ns_net_init。
static __net_init int net_ns_net_init(struct net *net)
{
#ifdef CONFIG_NET_NS
net->ns.ops =&netns_operations;
#endif
return ns_alloc_inum(&net->ns);
}
网络命名空间刚建立时,只包括网络环回设备。
1.网络命名空间管理
可以使用ip netns来执行建立、删除、显示网络命名空间。
l 创建网络命名空间ns1

#ip netns add ns1
会创建文件/var/run/netns/ns1。然后关联至网络命名空间/proc/self/ns/net。注意的是网络命名空间可以嵌套创建的。
l #ip netns del ns1
可以将网络命名空间进行删除。如果有一个或多个进程与这个网络命名空间相关联,就不会删除该命名空间。网络命名空间被删除时,所有网络设备都移至默认的初始网络命名空间init_net中。
l #ip netns list
可以显示所有通过ip netns add添加的网络命名空间。并不会添加其它诸如unshare创建的网络命名空间。
l 监视网络命名空间的建立跟删除,可以使用#ip netns monitor
l 指定网络命名空间中开启shell
可以使用命令ip netns exec ns1 bash
或者执行# ip netns exec ns1 ifconfig -a
可以显示ns1网络命名空间中所有网络接口,这个命令执行是docker是最像的。
l 显示指定pid相关联的网络命名空间
可以使用命令#ip netns identify #pid
例如:
#ip netns identify 1
l 显示与网络命名空间ns1相关联的进程PID
可以使用名了#ip netns pids ns1
l 网络接口移到另一个网络命名空间
#ip link set eth0 netns ns1
该命令会在net_device对象中添加新特性NETIF_F_NETNS_LOCAL。该特性表示网络设施是网络命名空间的本地设备,会调用函数dev_change_net_namespace。然后这个eth0就要在ns1空间中能够看到。
通过命令可以查看设备能否是网络命名空间的本地设备。
# ethtool -k enp0s3 | grep -i netns-local
设置无线网络接口移至其它网络命名空间,使用iw命令。
查看当前网络设施的命名命名空间,
2.命名空间之间通信
网络命名空间之间通信可以使用Unix套接字linux 命名空间,也可以使用虚拟以太网(VETH)网络驱动程序来建立一对虚拟网络设备,将其中给一个移至另一个网络命名空间中。例如:
#ip netns add ns1
#ip netns add ns2
在ns1中启动shell
# ip netnsexec ns1 bash
创建虚拟以太网设备,类型为veth.
# ip link add name if_one type veth peer nameif_one_peer
将if_one_peer移动到ns2中
# ip link set dev if_one_peer netns ns2
这样就在ns1和ns2中都用了一个网络接口,可以借助修改IP来进行通信了。
支持网络命名空间,需要配置内核参数CONFIG_NET_NS.
版权声明:本文内容由互联网用户自发贡献,版权归作者所有,本社区不拥有所有权,也不承担相关法律责任。如果您看到本社区中有涉嫌剽窃的内容linux 命名空间,欢迎发送邮件到:yqgroup@service.aliyun.com进行举报,并提供相关证据,一经查实,本社区将立即删除涉嫌侵权内容。
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-142263-1.html
小男神太棒了爱你
预计
里面的年轻人都说中国有如今的成就都是台湾帮助大陆发展经济和科技的