【OVS2.5.0源码分析】upcall处理线程分析(4)
来源:互联网 发布:java基础面试题 编辑:程序博客网 时间:2024/06/13 09:46
前两篇分析了接收netlink消息和解析netlink消息生成upcall对象,本篇分析upcall的处理。 处理函数为process_upcall。
1、process_upcall函数
static intprocess_upcall(struct udpif *udpif, struct upcall *upcall, struct ofpbuf *odp_actions, struct flow_wildcards *wc){ const struct nlattr *userdata = upcall->userdata; const struct dp_packet *packet = upcall->packet; const struct flow *flow = upcall->flow; switch (classify_upcall(upcall->type, userdata)) { case MISS_UPCALL: upcall_xlate(udpif, upcall, odp_actions, wc); return 0; case SFLOW_UPCALL: if (upcall->sflow) { union user_action_cookie cookie; const struct nlattr *actions; size_t actions_len = 0; struct dpif_sflow_actions sflow_actions; memset(&sflow_actions, 0, sizeof sflow_actions); memset(&cookie, 0, sizeof cookie); memcpy(&cookie, nl_attr_get(userdata), sizeof cookie.sflow); if (upcall->actions) { /* Actions were passed up from datapath. */ actions = nl_attr_get(upcall->actions); actions_len = nl_attr_get_size(upcall->actions); if (actions && actions_len) { dpif_sflow_read_actions(flow, actions, actions_len, &sflow_actions); } } if (actions_len == 0) { /* Lookup actions in userspace cache. */ struct udpif_key *ukey = ukey_lookup(udpif, upcall->ufid); if (ukey) { ukey_get_actions(ukey, &actions, &actions_len); dpif_sflow_read_actions(flow, actions, actions_len, &sflow_actions); } } dpif_sflow_received(upcall->sflow, packet, flow, flow->in_port.odp_port, &cookie, actions_len > 0 ? &sflow_actions : NULL); } break; case IPFIX_UPCALL: if (upcall->ipfix) { union user_action_cookie cookie; struct flow_tnl output_tunnel_key; memset(&cookie, 0, sizeof cookie); memcpy(&cookie, nl_attr_get(userdata), sizeof cookie.ipfix); if (upcall->out_tun_key) { odp_tun_key_from_attr(upcall->out_tun_key, false, &output_tunnel_key); } dpif_ipfix_bridge_sample(upcall->ipfix, packet, flow, flow->in_port.odp_port, cookie.ipfix.output_odp_port, upcall->out_tun_key ? &output_tunnel_key : NULL); } break; case FLOW_SAMPLE_UPCALL: if (upcall->ipfix) { union user_action_cookie cookie; memset(&cookie, 0, sizeof cookie); memcpy(&cookie, nl_attr_get(userdata), sizeof cookie.flow_sample); /* The flow reflects exactly the contents of the packet. * Sample the packet using it. */ dpif_ipfix_flow_sample(upcall->ipfix, packet, flow, cookie.flow_sample.collector_set_id, cookie.flow_sample.probability, cookie.flow_sample.obs_domain_id, cookie.flow_sample.obs_point_id); } break; case BAD_UPCALL: break; } return EAGAIN;}
从该函数可见,一共有4中upcall,MISS_UPCALL(未命中流表)、SFLOW_UPCALL(sFlow)、IPFIX_UPCALL和FLOW_SAMPLE_UPCALL。而datapath一共发送两种类型的netlink消息,OVS_PACKET_CMD_MISS和OVS_PACKET_CMD_ACTION。 upcall类型的映射关系通过classify_upcall函数实现:
static enum upcall_typeclassify_upcall(enum dpif_upcall_type type, const struct nlattr *userdata){ union user_action_cookie cookie; size_t userdata_len; /* First look at the upcall type. */ switch (type) { case DPIF_UC_ACTION: //OVS_PACKET_CMD_ACTION,即通过output_userspace发送netlink消息,需要进一步细化 break; case DPIF_UC_MISS: return MISS_UPCALL; //OVS_PACKET_CMD_MISS对应 case DPIF_N_UC_TYPES: default: VLOG_WARN_RL(&rl, "upcall has unexpected type %"PRIu32, type); return BAD_UPCALL; } /* "action" upcalls need a closer look. */ if (!userdata) { VLOG_WARN_RL(&rl, "action upcall missing cookie"); return BAD_UPCALL; } userdata_len = nl_attr_get_size(userdata); if (userdata_len < sizeof cookie.type || userdata_len > sizeof cookie) { VLOG_WARN_RL(&rl, "action upcall cookie has unexpected size %"PRIuSIZE, userdata_len); return BAD_UPCALL; } memset(&cookie, 0, sizeof cookie); memcpy(&cookie, nl_attr_get(userdata), userdata_len); //根据user data,进一步细分upcall类型 if (userdata_len == MAX(8, sizeof cookie.sflow) && cookie.type == USER_ACTION_COOKIE_SFLOW) { return SFLOW_UPCALL; //sflow } else if (userdata_len == MAX(8, sizeof cookie.slow_path) && cookie.type == USER_ACTION_COOKIE_SLOW_PATH) { return MISS_UPCALL; //miss_upcall, 主动重新刷新流表? } else if (userdata_len == MAX(8, sizeof cookie.flow_sample) && cookie.type == USER_ACTION_COOKIE_FLOW_SAMPLE) { return FLOW_SAMPLE_UPCALL; //sample } else if (userdata_len == MAX(8, sizeof cookie.ipfix) && cookie.type == USER_ACTION_COOKIE_IPFIX) { return IPFIX_UPCALL; //ipfix } else { VLOG_WARN_RL(&rl, "invalid user cookie of type %"PRIu16 " and size %"PRIuSIZE, cookie.type, userdata_len); return BAD_UPCALL; }}关于不同upcall的处理,将以专题的方式开展。 这样可以对某个功能有个全方位的了解,包括配置、upcall处理、流表生成等等。
0 0
- 【OVS2.5.0源码分析】upcall处理线程分析(4)
- 【OVS2.5.0源码分析】upcall处理线程分析(1)
- 【OVS2.5.0源码分析】upcall处理线程分析(2)
- 【OVS2.5.0源码分析】upcall处理线程分析(3)
- 【OVS2.5.0源码分析】openflow连接实现分析(4)
- 【OVS2.5.0源码分析】datapath之action分析(4)
- 【OVS2.5.0源码分析】bridge&bundle&port分析(1)
- 【OVS2.5.0源码分析】openflow连接实现分析(1)
- 【OVS2.5.0源码分析】openflow连接实现分析(2)
- 【OVS2.5.0源码分析】openflow连接实现分析(3)
- 【OVS2.5.0源码分析】openflow连接实现分析(5)
- 【OVS2.5.0源码分析】openflow连接实现分析(6)
- 【OVS2.5.0源码分析】ovsd进程运行机制分析(1)
- 【OVS2.5.0源码分析】datapath之action分析(1)
- 【OVS2.5.0源码分析】datapath之action分析(2)
- 【OVS2.5.0源码分析】datapath之action分析(3)
- 【OVS2.5.0源码分析】datapath之action分析(5)
- 【OVS2.5.0源码分析】datapath之action分析(6)
- JSP中的三大乱码问题
- springmvc和struts2的区别
- 开发团队里是否需要测试人员?
- Quartz Cron 表达式
- Virtual Friends
- 【OVS2.5.0源码分析】upcall处理线程分析(4)
- LeetCode之Intersection of Two Arrays
- jQuery 知识点 (四) —— jQuery 常用的的 DOM 函数
- SODBASE CEP学习(十五):常见场景EPL示例
- Nginx配置性能优化
- 一篇检讨
- MFC开发的软件文本框输入汉字变为一个个问号?
- 深入理解Android的startservice和bindservice
- 剑指offer[7]跳台阶