/*
- * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc.
+ * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include "packets.h"
#include "poll-loop.h"
#include "timeval.h"
-#include "vlog.h"
+#include "openvswitch/vlog.h"
VLOG_DEFINE_THIS_MODULE(in_band);
/* What to do to an in_band_rule. */
enum in_band_op {
ADD, /* Add the rule to ofproto's flow table. */
- DELETE /* Delete the rule from ofproto's flow table. */
+ DEL /* Delete the rule from ofproto's flow table. */
};
/* A rule to add to or delete from ofproto's flow table. */
struct in_band_rule {
struct hmap_node hmap_node; /* In struct in_band's "rules" hmap. */
struct match match;
- unsigned int priority;
+ int priority;
enum in_band_op op;
};
&next_hop_inaddr, &next_hop_dev);
if (retval) {
VLOG_WARN("cannot find route for controller ("IP_FMT"): %s",
- IP_ARGS(r->remote_addr.sin_addr.s_addr), strerror(retval));
+ IP_ARGS(r->remote_addr.sin_addr.s_addr),
+ ovs_strerror(retval));
return 1;
}
if (!next_hop_inaddr.s_addr) {
VLOG_WARN_RL(&rl, "cannot open netdev %s (next hop "
"to controller "IP_FMT"): %s",
next_hop_dev, IP_ARGS(r->remote_addr.sin_addr.s_addr),
- strerror(retval));
+ ovs_strerror(retval));
free(next_hop_dev);
return 1;
}
r->remote_mac);
if (retval) {
VLOG_DBG_RL(&rl, "cannot look up remote MAC address ("IP_FMT"): %s",
- IP_ARGS(next_hop_inaddr.s_addr), strerror(retval));
+ IP_ARGS(next_hop_inaddr.s_addr), ovs_strerror(retval));
}
/* If we don't have a MAC address, then refresh quickly, since we probably
return true;
}
-/* Returns true if the rule that would match 'flow' with 'actions' is
- * allowed to be set up in the datapath. */
+/* Returns true if packets in 'flow' should be directed to the local port.
+ * (This keeps the flow table from preventing DHCP replies from being seen by
+ * the local port.) */
bool
-in_band_rule_check(const struct flow *flow, odp_port_t local_odp_port,
- const struct nlattr *actions, size_t actions_len)
+in_band_must_output_to_local_port(const struct flow *flow)
{
- /* Don't allow flows that would prevent DHCP replies from being seen
- * by the local port. */
- if (flow->dl_type == htons(ETH_TYPE_IP)
+ return (flow->dl_type == htons(ETH_TYPE_IP)
&& flow->nw_proto == IPPROTO_UDP
&& flow->tp_src == htons(DHCP_SERVER_PORT)
- && flow->tp_dst == htons(DHCP_CLIENT_PORT)) {
- const struct nlattr *a;
- unsigned int left;
-
- NL_ATTR_FOR_EACH_UNSAFE (a, left, actions, actions_len) {
- if (nl_attr_type(a) == OVS_ACTION_ATTR_OUTPUT
- && nl_attr_get_odp_port(a) == local_odp_port) {
- return true;
- }
- }
- return false;
- }
+ && flow->tp_dst == htons(DHCP_CLIENT_PORT));
+}
- return true;
+/* Returns the number of in-band rules currently installed in the flow
+ * table. */
+int
+in_band_count_rules(const struct in_band *ib)
+{
+ return hmap_count(&ib->rules);
}
static void
-add_rule(struct in_band *ib, const struct match *match, unsigned int priority)
+add_rule(struct in_band *ib, const struct match *match, int priority)
{
uint32_t hash = match_hash(match, 0);
struct in_band_rule *rule;
/* Mark all the existing rules for deletion. (Afterward we will re-add any
* rules that are still valid.) */
HMAP_FOR_EACH (ib_rule, hmap_node, &ib->rules) {
- ib_rule->op = DELETE;
+ ib_rule->op = DEL;
}
if (ib->n_remotes && !eth_addr_is_zero(ib->local_mac)) {
ofpacts.data, ofpacts.size);
break;
- case DELETE:
- if (ofproto_delete_flow(ib->ofproto,
- &rule->match, rule->priority)) {
- /* ofproto doesn't have the rule anymore so there's no reason
- * for us to track it any longer. */
- hmap_remove(&ib->rules, &rule->hmap_node);
- free(rule);
- }
+ case DEL:
+ ofproto_delete_flow(ib->ofproto, &rule->match, rule->priority);
+ hmap_remove(&ib->rules, &rule->hmap_node);
+ free(rule);
break;
}
}
error = netdev_open(local_name, "internal", &local_netdev);
if (error) {
VLOG_ERR("failed to initialize in-band control: cannot open "
- "datapath local port %s (%s)", local_name, strerror(error));
+ "datapath local port %s (%s)",
+ local_name, ovs_strerror(error));
return error;
}