【OVS2.5.0源码分析】upcall处理线程分析(3)
来源:互联网 发布:linux msleep函数 编辑:程序博客网 时间:2024/06/06 00:05
第一篇介绍了netlink消息的接收,接收到的消息是最原始的消息格式,本篇介绍如何把原始的消息,转化为upcall对象。
1、parse_odp_packet函数
static intparse_odp_packet(const struct dpif_netlink *dpif, struct ofpbuf *buf, struct dpif_upcall *upcall, int *dp_ifindex){ static const struct nl_policy ovs_packet_policy[] = { /* Always present. */ [OVS_PACKET_ATTR_PACKET] = { .type = NL_A_UNSPEC, .min_len = ETH_HEADER_LEN }, [OVS_PACKET_ATTR_KEY] = { .type = NL_A_NESTED }, /* OVS_PACKET_CMD_ACTION only. */ [OVS_PACKET_ATTR_USERDATA] = { .type = NL_A_UNSPEC, .optional = true }, [OVS_PACKET_ATTR_EGRESS_TUN_KEY] = { .type = NL_A_NESTED, .optional = true }, [OVS_PACKET_ATTR_ACTIONS] = { .type = NL_A_NESTED, .optional = true }, [OVS_PACKET_ATTR_MRU] = { .type = NL_A_U16, .optional = true } }; struct ovs_header *ovs_header; struct nlattr *a[ARRAY_SIZE(ovs_packet_policy)]; struct nlmsghdr *nlmsg; struct genlmsghdr *genl; struct ofpbuf b; int type; ofpbuf_use_const(&b, buf->data, buf->size); nlmsg = ofpbuf_try_pull(&b, sizeof *nlmsg); //获取nlmsghdr信息 genl = ofpbuf_try_pull(&b, sizeof *genl); //获取genlmsghdr信息 ovs_header = ofpbuf_try_pull(&b, sizeof *ovs_header); //获取ovs_header信息 if (!nlmsg || !genl || !ovs_header || nlmsg->nlmsg_type != ovs_packet_family || !nl_policy_parse(&b, 0, ovs_packet_policy, a, //获取其他属性信息 ARRAY_SIZE(ovs_packet_policy))) { return EINVAL; } type = (genl->cmd == OVS_PACKET_CMD_MISS ? DPIF_UC_MISS : genl->cmd == OVS_PACKET_CMD_ACTION ? DPIF_UC_ACTION : -1); if (type < 0) { return EINVAL; } /* (Re)set ALL fields of '*upcall' on successful return. */ upcall->type = type; upcall->key = CONST_CAST(struct nlattr *, nl_attr_get(a[OVS_PACKET_ATTR_KEY])); upcall->key_len = nl_attr_get_size(a[OVS_PACKET_ATTR_KEY]); dpif_flow_hash(&dpif->dpif, upcall->key, upcall->key_len, &upcall->ufid); upcall->userdata = a[OVS_PACKET_ATTR_USERDATA]; upcall->out_tun_key = a[OVS_PACKET_ATTR_EGRESS_TUN_KEY]; upcall->actions = a[OVS_PACKET_ATTR_ACTIONS]; upcall->mru = a[OVS_PACKET_ATTR_MRU]; /* Allow overwriting the netlink attribute header without reallocating. */ dp_packet_use_stub(&upcall->packet, //构建upcall->packet对象,包括base指针、data指针、长度等信息 CONST_CAST(struct nlattr *, nl_attr_get(a[OVS_PACKET_ATTR_PACKET])) - 1, nl_attr_get_size(a[OVS_PACKET_ATTR_PACKET]) + sizeof(struct nlattr)); dp_packet_set_data(&upcall->packet, (char *)dp_packet_data(&upcall->packet) + sizeof(struct nlattr)); dp_packet_set_size(&upcall->packet, nl_attr_get_size(a[OVS_PACKET_ATTR_PACKET])); *dp_ifindex = ovs_header->dp_ifindex; return 0;}2、nl_policy_parse函数
/* Parses the 'msg' starting at the given 'nla_offset' as a sequence of Netlink * attributes. 'policy[i]', for 0 <= i < n_attrs, specifies how the attribute * with nla_type == i is parsed; a pointer to attribute i is stored in * attrs[i]. Returns true if successful, false on failure. * * If the Netlink attributes in 'msg' follow a Netlink header and a Generic * Netlink header, then 'nla_offset' should be NLMSG_HDRLEN + GENL_HDRLEN. */boolnl_policy_parse(const struct ofpbuf *msg, size_t nla_offset, const struct nl_policy policy[], struct nlattr *attrs[], size_t n_attrs){ struct nlattr *nla; size_t left; size_t i; memset(attrs, 0, n_attrs * sizeof *attrs); if (msg->size < nla_offset) { VLOG_DBG_RL(&rl, "missing headers in nl_policy_parse"); return false; } NL_ATTR_FOR_EACH (nla, left, ofpbuf_at(msg, nla_offset, 0), //获取netlink的其他属性 msg->size - nla_offset) { uint16_t type = nl_attr_type(nla); if (type < n_attrs && policy[type].type != NL_A_NO_ATTR) { const struct nl_policy *e = &policy[type]; if (!nl_attr_validate(nla, e)) { return false; } if (attrs[type]) { VLOG_DBG_RL(&rl, "duplicate attr %"PRIu16, type); } attrs[type] = nla; } } if (left) { VLOG_DBG_RL(&rl, "attributes followed by garbage"); return false; } for (i = 0; i < n_attrs; i++) { //检查必须字段是否有值 const struct nl_policy *e = &policy[i]; if (!e->optional && e->type != NL_A_NO_ATTR && !attrs[i]) { VLOG_DBG_RL(&rl, "required attr %"PRIuSIZE" missing", i); return false; } } return true;}
0 0
- 【OVS2.5.0源码分析】upcall处理线程分析(3)
- 【OVS2.5.0源码分析】upcall处理线程分析(1)
- 【OVS2.5.0源码分析】upcall处理线程分析(2)
- 【OVS2.5.0源码分析】upcall处理线程分析(4)
- 【OVS2.5.0源码分析】openflow连接实现分析(3)
- 【OVS2.5.0源码分析】datapath之action分析(3)
- 【OVS2.5.0源码分析】sFlow实现分析(3)
- 【OVS2.5.0源码分析】bridge&bundle&port分析(1)
- 【OVS2.5.0源码分析】openflow连接实现分析(1)
- 【OVS2.5.0源码分析】openflow连接实现分析(2)
- 【OVS2.5.0源码分析】openflow连接实现分析(4)
- 【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分析(4)
- 【OVS2.5.0源码分析】datapath之action分析(5)
- 进入Activity停止几秒后直接跳转
- java语言程序设计基础篇第十一章编程练习题
- servlet <load-on-startup>设置时遇到的问题
- jquery插件开发
- ASP.NET ASHX 一般处理程序教程
- 【OVS2.5.0源码分析】upcall处理线程分析(3)
- bootstrap-validator自定义验证规则,修改验证事件为blur
- java语言程序设计基础篇第十二章编程练习题
- Spring4 MVC HelloWord实例
- 脚本 网格 渲染
- Java笔记-Integer类
- ListView的简单使用
- Mesh Filter Text Mesh Mesh Renderer:
- php页面相调用过程