这来主要看看ovs从网络接口收到packet后的一系列操作。
在内核模块启动的时候会初始化vport子系统(ovs_vport_init),各种vport类型,那么什么时候会调用相应的函数与实际网络设备建立联系?其实当我们在为网桥增设端口的时候,就会进入ovs_netdev_vport_ops中的create方法,进而 注册网络设备。
struct netdev_vport {
struct rcu_head rcu;
struct net_device *dev;
};
struct rcu_head rcu;
struct net_device *dev;
};
const struct vport_ops ovs_netdev_vport_ops = {
.type = OVS_VPORT_TYPE_NETDEV,
.flags = VPORT_F_REQUIRED,
.init = netdev_init, //之后的内核版本,这里直接return 0;
.exit = netdev_exit,
.create = netdev_create,
.destroy = netdev_destroy,
.set_addr = ovs_netdev_set_addr,
.get_name = ovs_netdev_get_name,
.get_addr = ovs_netdev_get_addr,
.get_kobj = ovs_netdev_get_kobj,
.get_dev_flags = ovs_netdev_get_dev_flags,
.is_running = ovs_netdev_is_running,
.get_operstate = ovs_netdev_get_operstate,
.get_ifindex = ovs_netdev_get_ifindex,
.get_mtu = ovs_netdev_get_mtu,
.send = netdev_send,
};
.type = OVS_VPORT_TYPE_NETDEV,
.flags = VPORT_F_REQUIRED,
.init = netdev_init, //之后的内核版本,这里直接return 0;
.exit = netdev_exit,
.create = netdev_create,
.destroy = netdev_destroy,
.set_addr = ovs_netdev_set_addr,
.get_name = ovs_netdev_get_name,
.get_addr = ovs_netdev_get_addr,
.get_kobj = ovs_netdev_get_kobj,
.get_dev_flags = ovs_netdev_get_dev_flags,
.is_running = ovs_netdev_is_running,
.get_operstate = ovs_netdev_get_operstate,
.get_ifindex = ovs_netdev_get_ifindex,
.get_mtu = ovs_netdev_get_mtu,
.send = netdev_send,
};
--datapath/vport-netdev.c
static struct vport *netdev_create(const struct vport_parms *parms)
{
struct vport *vport;
struct netdev_vport *netdev_vport;
int err;
vport = ovs_vport_alloc(sizeof(struct netdev_vport), &ovs_netdev_vport_ops, parms);
{
struct vport *vport;
struct netdev_vport *netdev_vport;
int err;
vport = ovs_vport_alloc(sizeof(struct netdev_vport), &ovs_netdev_vport_ops, parms);
//有ovs_netdev_vport_ops和vport parameters 来构造初始化一个vport;
netdev_vport = netdev_vport_priv(vport);
//获得vport
//获得vport