- ofservice = xzalloc(sizeof *ofservice);
- hmap_insert(&ofproto->services, &ofservice->node,
- hash_string(c->target, 0));
- ofservice->pvconn = pvconn;
-
- ofservice_reconfigure(ofservice, c);
-
- return 0;
-}
-
-static void
-ofservice_destroy(struct ofproto *ofproto, struct ofservice *ofservice)
-{
- hmap_remove(&ofproto->services, &ofservice->node);
- pvconn_close(ofservice->pvconn);
- free(ofservice);
-}
-
-/* Finds and returns the ofservice within 'ofproto' that has the given
- * 'target', or a null pointer if none exists. */
-static struct ofservice *
-ofservice_lookup(struct ofproto *ofproto, const char *target)
-{
- struct ofservice *ofservice;
-
- HMAP_FOR_EACH_WITH_HASH (ofservice, node, hash_string(target, 0),
- &ofproto->services) {
- if (!strcmp(pvconn_get_name(ofservice->pvconn), target)) {
- return ofservice;
- }
- }
- return NULL;
-}
-\f
-/* Returns true if 'rule' should be hidden from the controller.
- *
- * Rules with priority higher than UINT16_MAX are set up by ofproto itself
- * (e.g. by in-band control) and are intentionally hidden from the
- * controller. */
-static bool
-rule_is_hidden(const struct rule *rule)
-{
- return rule->cr.priority > UINT16_MAX;
-}
-
-/* Creates and returns a new rule initialized as specified.
- *
- * The caller is responsible for inserting the rule into the classifier (with
- * rule_insert()). */
-static struct rule *
-rule_create(const struct cls_rule *cls_rule,
- const union ofp_action *actions, size_t n_actions,
- uint16_t idle_timeout, uint16_t hard_timeout,
- ovs_be64 flow_cookie, bool send_flow_removed)
-{
- struct rule *rule = xzalloc(sizeof *rule);
- rule->cr = *cls_rule;
- rule->idle_timeout = idle_timeout;
- rule->hard_timeout = hard_timeout;
- rule->flow_cookie = flow_cookie;
- rule->used = rule->created = time_msec();
- rule->send_flow_removed = send_flow_removed;
- list_init(&rule->facets);
- if (n_actions > 0) {
- rule->n_actions = n_actions;
- rule->actions = xmemdup(actions, n_actions * sizeof *actions);
- }
-
- return rule;
-}
-
-static struct rule *
-rule_from_cls_rule(const struct cls_rule *cls_rule)
-{
- return cls_rule ? CONTAINER_OF(cls_rule, struct rule, cr) : NULL;
-}
-
-static void
-rule_free(struct rule *rule)
-{
- free(rule->actions);
- free(rule);
-}
-
-/* Destroys 'rule' and iterates through all of its facets and revalidates them,
- * destroying any that no longer has a rule (which is probably all of them).
- *
- * The caller must have already removed 'rule' from the classifier. */
-static void
-rule_destroy(struct ofproto *ofproto, struct rule *rule)
-{
- struct facet *facet, *next_facet;
- LIST_FOR_EACH_SAFE (facet, next_facet, list_node, &rule->facets) {
- facet_revalidate(ofproto, facet);
- }
- rule_free(rule);
-}
-
-/* Returns true if 'rule' has an OpenFlow OFPAT_OUTPUT or OFPAT_ENQUEUE action
- * that outputs to 'out_port' (output to OFPP_FLOOD and OFPP_ALL doesn't
- * count). */
-static bool
-rule_has_out_port(const struct rule *rule, ovs_be16 out_port)
-{
- const union ofp_action *oa;
- struct actions_iterator i;
-
- if (out_port == htons(OFPP_NONE)) {
- return true;
- }
- for (oa = actions_first(&i, rule->actions, rule->n_actions); oa;
- oa = actions_next(&i)) {
- if (action_outputs_to_port(oa, out_port)) {
- return true;
- }
- }
- return false;
-}
-
-/* Executes, within 'ofproto', the 'n_actions' actions in 'actions' on
- * 'packet', which arrived on 'in_port'.
- *
- * Takes ownership of 'packet'. */
-static bool
-execute_odp_actions(struct ofproto *ofproto, const struct flow *flow,
- const struct nlattr *odp_actions, size_t actions_len,
- struct ofpbuf *packet)
-{
- if (actions_len == NLA_ALIGN(NLA_HDRLEN + sizeof(uint64_t))
- && odp_actions->nla_type == ODP_ACTION_ATTR_CONTROLLER) {
- /* As an optimization, avoid a round-trip from userspace to kernel to
- * userspace. This also avoids possibly filling up kernel packet
- * buffers along the way. */
- struct dpif_upcall upcall;
-
- upcall.type = DPIF_UC_ACTION;
- upcall.packet = packet;
- upcall.key = NULL;
- upcall.key_len = 0;
- upcall.userdata = nl_attr_get_u64(odp_actions);
- upcall.sample_pool = 0;
- upcall.actions = NULL;
- upcall.actions_len = 0;
-
- send_packet_in(ofproto, &upcall, flow, false);
-
- return true;