union odp_action *odp_actions;
};
+static inline bool
+rule_is_hidden(const struct rule *rule)
+{
+ /* Subrules are merely an implementation detail, so hide them from the
+ * controller. */
+ if (rule->super != NULL) {
+ return true;
+ }
+
+ /* Rules with priority higher than UINT16_MAX are set up by secchan itself
+ * (e.g. by in-band control) and are intentionally hidden from the
+ * controller. */
+ if (rule->cr.priority > UINT16_MAX) {
+ return true;
+ }
+
+ return false;
+}
+
static struct rule *rule_create(struct rule *super, const union ofp_action *,
size_t n_actions, uint16_t idle_timeout,
uint16_t hard_timeout);
{
if (in_band != (p->in_band != NULL)) {
if (in_band) {
- return in_band_create(&p->dpif, p->switch_status,
+ return in_band_create(p, &p->dpif, p->switch_status,
p->controller->rconn, &p->in_band);
} else {
ofproto_set_discovery(p, false, NULL, true);
void
ofproto_add_flow(struct ofproto *p,
- const flow_t *flow, uint32_t wildcards, uint16_t priority,
+ const flow_t *flow, uint32_t wildcards, unsigned int priority,
const union ofp_action *actions, size_t n_actions,
const struct ofpbuf *packet, int idle_timeout)
{
void
ofproto_delete_flow(struct ofproto *ofproto, const flow_t *flow,
- uint32_t wildcards, uint16_t priority)
+ uint32_t wildcards, unsigned int priority)
{
struct rule *rule;
uint64_t packet_count, byte_count;
size_t act_len, len;
- if (rule->super || !rule_has_out_port(rule, cbdata->out_port)) {
+ if (rule_is_hidden(rule) || !rule_has_out_port(rule, cbdata->out_port)) {
return;
}
struct aggregate_stats_cbdata *cbdata = cbdata_;
uint64_t packet_count, byte_count;
- if (rule->super || !rule_has_out_port(rule, cbdata->out_port)) {
+ if (rule_is_hidden(rule) || !rule_has_out_port(rule, cbdata->out_port)) {
return;
}
modify_flow(struct ofproto *p, const struct ofp_flow_mod *ofm,
size_t n_actions, uint16_t command, struct rule *rule)
{
- if (rule->super) {
- /* Subrules are invisible to the controller. */
+ if (rule_is_hidden(rule)) {
return 0;
}
subrule = rule_create(rule, NULL, 0,
rule->idle_timeout, rule->hard_timeout);
- cls_rule_from_flow(&subrule->cr, &flow, 0, 0);
+ cls_rule_from_flow(&subrule->cr, &flow, 0,
+ (rule->cr.priority <= UINT16_MAX ? UINT16_MAX
+ : rule->cr.priority));
old_sr = rule_from_cls_rule(classifier_insert(&p->cls, &subrule->cr));
if (old_sr) {
int ofproto_send_packet(struct ofproto *, const flow_t *,
const union ofp_action *, size_t n_actions,
const struct ofpbuf *);
-void ofproto_add_flow(struct ofproto *,
- const flow_t *, uint32_t wildcards, uint16_t priority,
+void ofproto_add_flow(struct ofproto *, const flow_t *, uint32_t wildcards,
+ unsigned int priority,
const union ofp_action *, size_t n_actions,
const struct ofpbuf *, int idle_timeout);
void ofproto_delete_flow(struct ofproto *, const flow_t *, uint32_t wildcards,
- uint16_t priority);
+ unsigned int priority);
void ofproto_flush_flows(struct ofproto *);
/* Hooks for vswitchd. */