之前的工作对ovs应用层比较熟悉,但没有看过ovs的源码,所以这里大概瞄了一眼,宏观的一些记录。
struct vport {
struct net_device *dev;
struct datapath *dp;
struct vport_portids __rcu *upcall_portids;
u16 port_no;
struct hlist_node hash_node;
struct hlist_node dp_hash_node;
const struct vport_ops *ops;
struct list_head detach_list;
struct rcu_head rcu;
};
struct datapath {
struct rcu_head rcu;
struct list_head list_node;
/* Flow table. */
struct flow_table table;
/* Switch ports. */
struct hlist_head *ports;
/* Stats. */
struct dp_stats_percpu __percpu *stats_percpu;
/* Network namespace ref. */
possible_net_t net;
u32 user_features;
u32 max_headroom;
};
struct flow_table {
struct table_instance __rcu *ti;
struct table_instance __rcu *ufid_ti;
struct mask_cache_entry __percpu *mask_cache;
struct mask_array __rcu *mask_array;
unsigned long last_rehash;
unsigned int count;
unsigned int ufid_count;
};
参见ovs-2.8.1/datapath/flow.h:68
参见ovs-2.8.1/ofproto/ofproto-provider.h:351
struct rule_actions {
/* Flags.
*
* 'has_meter' is true if 'ofpacts' contains an OFPACT_METER action.
*
* 'has_learn_with_delete' is true if 'ofpacts' contains an OFPACT_LEARN
* action whose flags include NX_LEARN_F_DELETE_LEARNED. */
bool has_meter;
bool has_learn_with_delete;
bool has_groups;
/* Actions. */
uint32_t ofpacts_len; /* Size of 'ofpacts', in bytes. */
struct ofpact ofpacts[]; /* Sequence of "struct ofpacts". */
};
挂到kernel上,注册对应函数,来一个报文时ovs的入口函数为: int ovs_vport_receive(struct vport *vport, struct sk_buff *skb, const struct ip_tunnel_info *tun_info)
后续会继续调用=void ovs_dp_process_packet(struct sk_buff *skb, struct sw_flow_key *key)= 这里会看到生成flow表的key,查表,send等所有细节。
对应的发送函数为: void ovs_vport_send(struct vport *vport, struct sk_buff *skb, u8 mac_proto)
static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
struct sw_flow_key *key,
const struct nlattr *attr, int len)
最常见的output action
static void do_output(struct datapath *dp, struct sk_buff *skb, int out_port,
struct sw_flow_key *key)
action的drop是作为默认处理的,在定义的如下enum中没有drop!如果这些都没有,程序跳入最后一行free skbbuff那里。
enum ovs_action_attr {
OVS_ACTION_ATTR_UNSPEC,
OVS_ACTION_ATTR_OUTPUT, /* u32 port number. */
OVS_ACTION_ATTR_USERSPACE, /* Nested OVS_USERSPACE_ATTR_*. */
...
有三种方式:
- 通过Remote Controller直接发送移除Flow Entry的消息,通过Openflow来做,这个没得说
- 通过OpenFlow Switch的过期机制, hard_timeout, idle_timeout在flow里看见过的,
- OpenFlow Switch的逐出机制,当OpenFlow Switch需要回收资源时,会行使这一权限,这个倒是很少见。
//ovs-2.8.1/include/openflow/openflow-1.0.h:29
/* Port number(s) meaning
* --------------- --------------------------------------
* 0x0000 not assigned a meaning by OpenFlow 1.0
* 0x0001...0xfeff "physical" ports
* 0xff00...0xfff6 "reserved" but not assigned a meaning by OpenFlow 1.x
* 0xfff7...0xffff "reserved" OFPP_* ports with assigned meanings
*/
/* Ranges. */
#define OFPP_MAX OFP_PORT_C(0xff00) /* Max # of switch ports. */
#define OFPP_FIRST_RESV OFP_PORT_C(0xfff7) /* First assigned reserved port. */
#define OFPP_LAST_RESV OFP_PORT_C(0xffff) /* Last assigned reserved port. */
/* Reserved output "ports". */
#define OFPP_UNSET OFP_PORT_C(0xfff7) /* For OXM_OF_ACTSET_OUTPUT only. */
#define OFPP_IN_PORT OFP_PORT_C(0xfff8) /* Where the packet came in. */
#define OFPP_TABLE OFP_PORT_C(0xfff9) /* Perform actions in flow table. */
#define OFPP_NORMAL OFP_PORT_C(0xfffa) /* Process with normal L2/L3. */
#define OFPP_FLOOD OFP_PORT_C(0xfffb) /* All ports except input port and
* ports disabled by STP. */
#define OFPP_ALL OFP_PORT_C(0xfffc) /* All ports except input port. */
#define OFPP_CONTROLLER OFP_PORT_C(0xfffd) /* Send to controller. */
#define OFPP_LOCAL OFP_PORT_C(0xfffe) /* Local openflow "port". */
#define OFPP_NONE OFP_PORT_C(0xffff) /* Not associated with any port. */