正确openvSwitch不同种类port认识


同一主机上的OVS中能够创建多个网桥(即多个datapath实例),每一个bridge能够通过patch ports互联,而netdev ports是OVS对底层物理port的抽象封装。internal 类型的port比較不好理解,能够看做每一个OVS交换机有个能够用来处理数据报的本地port。能够为这个网络设备配置 IP 地址(比方在把eth0增加某个bridge的时候,它的IP地址就失效了。能够把IP地址赋给br,这就是internal port的地址)等等。

     以下列出vport相关的数据结构,尽管前面的文章有涉及。可是不够集中全面。
/**
 * struct vport抽象的是datapath中的每一个端口,
 */
struct vport {
	struct rcu_head rcu; //RCU callback head for deferred destruction.
	u16 port_no;		//端口号是dp中ports数组的索引。
	struct datapath	*dp; //这个端口所属的datapath。
	struct kobject kobj;  // Represents /sys/class/net/<devname>/brport
	char linkname[IFNAMSIZ]; 
	u32 upcall_portid;   //在这个端口收到的包假设匹配流表失败会通过这个netlink port传至用户空间。

	struct hlist_node hash_node; //  vport.c中的哈希表dev_table使用;
	struct hlist_node dp_hash_node; //是结构体datapath->ports中的构成元素,将全部vport连接起来。
	const struct vport_ops *ops;   //核心,定义vport的类型(能做的操作)。

	struct vport_percpu_stats __percpu *percpu_stats;  //指向每一个CPU的统计信息;

	spinlock_t stats_lock;      //自旋锁,保护以下俩字段的訪问;
	struct vport_err_stats err_stats; //错误的统计信息;
	struct ovs_vport_stats offset_stats;  //过时了;
};
/**
 * struct vport_parms - parameters for creating a new vport
 * 端口參数。当创建一个新的vport端口是要传入的參数
 */
struct vport_parms {
	const char *name;
	enum ovs_vport_type type; //端口的类型
	struct nlattr *options; //保存从netlink msg中得到的属性

	/* For ovs_vport_alloc(). */
	struct datapath *dp; //端口属于哪个datapath(网桥)
	u16 port_no;   //端口号
	u32 upcall_portid;  //和用户空间通信的netlink 端口
};

/**
 * struct vport_ops -定义虚拟端口的类型(能做的操作)
 */
struct vport_ops {
	enum ovs_vport_type type; // 类型值,OVS_VPORT_TYPE_*。
	u32 flags;			// VPORT_F_*,影响通用虚拟端口层怎样处理这个vport。

	/* Called at module init and exit respectively. */
	int (*init)(void);		// 模块初始化;假设设置了标识VPORT_F_REQUIRED,那么该函数运行失败后
							//停止模块载入。否则仅仅是导致不创建这种类型的vport。

void (*exit)(void); //模块卸载之时。 /* Called with RTNL lock. */ struct vport *(*create)(const struct vport_parms *); //依据运行參数来创建一个新的vport,失败则返回相应的 ERR_PTR() 值; void (*destroy)(struct vport *); // 销毁这个vport,必须调用vport_free()释放(由于利用的是RCU。所以等到 RCU grace period之后实际运行) int (*set_options)(struct vport *, struct nlattr *); //配置这个vport,假设不支持改动,就把该函数指针置为Null。 int (*get_options)(const struct vport *, struct sk_buff *);//获得这个vport相关的配置属性到sk_buff中; int (*set_addr)(struct vport *, const unsigned char *);//设置MAC地址; /* Called with rcu_read_lock or RTNL lock. */ const char *(*get_name)(const struct vport *); // 设备名 const unsigned char *(*get_addr)(const struct vport *); void (*get_config)(const struct vport *, void *); struct kobject *(*get_kobj)(const struct vport *);//获得这个设备关联的kobj对象; unsigned (*get_dev_flags)(const struct vport *);//设备标志; int (*is_running)(const struct vport *); unsigned char (*get_operstate)(const struct vport *); //设备的工作状态 int (*get_ifindex)(const struct vport *);//和这个设备关联的接口号(system interface index ) int (*get_mtu)(const struct vport *);//设备的MTU,假设像tunnel这种就没有MTU,返回null; int (*send)(struct vport *, struct sk_buff *); //在该设备上发送一个packet,返回发送的长度; }; /* List of statically compiled vport implementations. Don't forget to also * add yours to the list at the top of vport.c. */ extern const struct vport_ops ovs_netdev_vport_ops; extern const struct vport_ops ovs_internal_vport_ops; extern const struct vport_ops ovs_patch_vport_ops;





版权声明:本文博客原创文章,博客,未经同意,不得转载。

原文地址:https://www.cnblogs.com/mfrbuaa/p/4737648.html