* reason to look at them. */
int recurse; /* Recursion level, via xlate_table_action. */
- int last_pop_priority; /* Offset in 'odp_actions' just past most
- * recent ODP_ACTION_ATTR_SET_PRIORITY. */
+ uint32_t priority; /* Current flow priority. 0 if none. */
+ struct flow base_flow; /* Flow at the last commit. */
+ uint32_t base_priority; /* Priority at the last commit. */
};
static void action_xlate_ctx_init(struct action_xlate_ctx *,
long long int used);
static void facet_update_stats(struct ofproto_dpif *, struct facet *,
const struct dpif_flow_stats *);
+static void facet_reset_dp_stats(struct facet *, struct dpif_flow_stats *);
static void facet_push_stats(struct facet *);
static void facet_account(struct ofproto_dpif *, struct facet *,
uint64_t extra_bytes);
static void port_run(struct ofport_dpif *);
static void port_wait(struct ofport_dpif *);
-static int set_cfm(struct ofport *, const struct cfm *,
- const uint16_t *remote_mps, size_t n_remote_mps);
+static int set_cfm(struct ofport *, const struct cfm_settings *);
struct ofproto_dpif {
struct ofproto up;
struct ofproto_dpif *ofproto = ofproto_dpif_cast(port->up.ofproto);
bundle_remove(port_);
- set_cfm(port_, NULL, NULL, 0);
+ set_cfm(port_, NULL);
if (ofproto->sflow) {
ofproto_sflow_del_port(ofproto->sflow, port->odp_port);
}
}
static int
-set_cfm(struct ofport *ofport_, const struct cfm *cfm,
- const uint16_t *remote_mps, size_t n_remote_mps)
+set_cfm(struct ofport *ofport_, const struct cfm_settings *s)
{
struct ofport_dpif *ofport = ofport_dpif_cast(ofport_);
int error;
- if (!cfm) {
+ if (!s) {
error = 0;
} else {
if (!ofport->cfm) {
- ofport->cfm = cfm_create();
+ ofport->cfm = cfm_create(netdev_get_name(ofport->up.netdev));
}
- ofport->cfm->mpid = cfm->mpid;
- ofport->cfm->interval = cfm->interval;
- ofport->cfm->name = cfm->name;
-
- cfm_update_remote_mps(ofport->cfm, remote_mps, n_remote_mps);
-
- if (cfm_configure(ofport->cfm)) {
+ if (cfm_configure(ofport->cfm, s)) {
return 0;
}
}
static int
-get_cfm(struct ofport *ofport_, const struct cfm **cfmp)
+get_cfm_fault(const struct ofport *ofport_)
{
struct ofport_dpif *ofport = ofport_dpif_cast(ofport_);
- *cfmp = ofport->cfm;
- return 0;
+
+ return ofport->cfm ? cfm_get_fault(ofport->cfm) : -1;
}
\f
/* Bundles. */
LIST_FOR_EACH (port, bundle_node, &bundle->ports) {
bool may_enable = lacp_slave_may_enable(bundle->lacp, port);
- bond_slave_set_lacp_may_enable(bundle->bond, port, may_enable);
+
+ if (may_enable && port->cfm) {
+ may_enable = !cfm_get_fault(port->cfm);
+ }
+ bond_slave_set_may_enable(bundle->bond, port, may_enable);
}
bond_run(bundle->bond, &bundle->ofproto->revalidate_set,
if (cfm_should_send_ccm(ofport->cfm)) {
struct ofpbuf packet;
- struct ccm *ccm;
ofpbuf_init(&packet, 0);
- ccm = eth_compose(&packet, eth_addr_ccm, ofport->up.opp.hw_addr,
- ETH_TYPE_CFM, sizeof *ccm);
- cfm_compose_ccm(ofport->cfm, ccm);
+ cfm_compose_ccm(ofport->cfm, &packet, ofport->up.opp.hw_addr);
send_packet(ofproto_dpif_cast(ofport->up.ofproto),
ofport->odp_port, &packet);
ofpbuf_uninit(&packet);
{
if (cfm_should_process_flow(flow)) {
struct ofport_dpif *ofport = get_ofp_port(ofproto, flow->in_port);
- if (ofport && ofport->cfm) {
+ if (packet && ofport && ofport->cfm) {
cfm_process_heartbeat(ofport->cfm, packet);
}
return true;
} else if (flow->dl_type == htons(ETH_TYPE_LACP)) {
struct ofport_dpif *port = get_ofp_port(ofproto, flow->in_port);
- if (port && port->bundle && port->bundle->lacp) {
+ if (packet && port && port->bundle && port->bundle->lacp) {
const struct lacp_pdu *pdu = parse_lacp_packet(packet);
if (pdu) {
lacp_process_pdu(port->bundle->lacp, port, pdu);
}
- return true;
}
+ return true;
}
return false;
}
return true;
} else {
+ struct odputil_keybuf keybuf;
+ struct ofpbuf key;
int error;
- error = dpif_execute(ofproto->dpif, odp_actions, actions_len, packet);
+ ofpbuf_use_stack(&key, &keybuf, sizeof keybuf);
+ odp_flow_key_from_flow(&key, flow);
+
+ error = dpif_execute(ofproto->dpif, key.data, key.size,
+ odp_actions, actions_len, packet);
+
ofpbuf_delete(packet);
return !error;
}
ofpbuf_delete(odp_actions);
}
+/* Updates 'facet''s flow in the datapath setting its actions to 'actions_len'
+ * bytes of actions in 'actions'. If 'stats' is non-null, statistics counters
+ * in the datapath will be zeroed and 'stats' will be updated with traffic new
+ * since 'facet' was last updated.
+ *
+ * Returns 0 if successful, otherwise a positive errno value.*/
static int
facet_put__(struct ofproto_dpif *ofproto, struct facet *facet,
const struct nlattr *actions, size_t actions_len,
struct odputil_keybuf keybuf;
enum dpif_flow_put_flags flags;
struct ofpbuf key;
+ int ret;
flags = DPIF_FP_CREATE | DPIF_FP_MODIFY;
if (stats) {
flags |= DPIF_FP_ZERO_STATS;
- facet->dp_packet_count = 0;
- facet->dp_byte_count = 0;
}
ofpbuf_use_stack(&key, &keybuf, sizeof keybuf);
odp_flow_key_from_flow(&key, &facet->flow);
- return dpif_flow_put(ofproto->dpif, flags, key.data, key.size,
- actions, actions_len, stats);
+ ret = dpif_flow_put(ofproto->dpif, flags, key.data, key.size,
+ actions, actions_len, stats);
+
+ if (stats) {
+ facet_reset_dp_stats(facet, stats);
+ }
+
+ return ret;
}
/* If 'facet' is installable, inserts or re-inserts it into 'p''s datapath. If
struct odputil_keybuf keybuf;
struct dpif_flow_stats stats;
struct ofpbuf key;
+ int error;
ofpbuf_use_stack(&key, &keybuf, sizeof keybuf);
odp_flow_key_from_flow(&key, &facet->flow);
- if (!dpif_flow_del(p->dpif, key.data, key.size, &stats)) {
+ error = dpif_flow_del(p->dpif, key.data, key.size, &stats);
+ facet_reset_dp_stats(facet, &stats);
+ if (!error) {
facet_update_stats(p, facet, &stats);
}
facet->installed = false;
- facet->dp_packet_count = 0;
- facet->dp_byte_count = 0;
} else {
assert(facet->dp_packet_count == 0);
assert(facet->dp_byte_count == 0);
htons(OFPP_CONTROLLER)));
}
+/* Resets 'facet''s datapath statistics counters. This should be called when
+ * 'facet''s statistics are cleared in the datapath. If 'stats' is non-null,
+ * it should contain the statistics returned by dpif when 'facet' was reset in
+ * the datapath. 'stats' will be modified to only included statistics new
+ * since 'facet' was last updated. */
+static void
+facet_reset_dp_stats(struct facet *facet, struct dpif_flow_stats *stats)
+{
+ if (stats && facet->dp_packet_count <= stats->n_packets
+ && facet->dp_byte_count <= stats->n_bytes) {
+ stats->n_packets -= facet->dp_packet_count;
+ stats->n_bytes -= facet->dp_byte_count;
+ }
+
+ facet->dp_packet_count = 0;
+ facet->dp_byte_count = 0;
+}
+
/* Folds all of 'facet''s statistics into its rule. Also updates the
* accounting ofhook and emits a NetFlow expiration if appropriate. All of
* 'facet''s statistics in the datapath should have been zeroed and folded into
send_packet(struct ofproto_dpif *ofproto, uint32_t odp_port,
const struct ofpbuf *packet)
{
- struct ofpbuf odp_actions;
+ struct ofpbuf key, odp_actions;
+ struct odputil_keybuf keybuf;
+ struct flow flow;
int error;
+ flow_extract((struct ofpbuf *) packet, 0, 0, &flow);
+ ofpbuf_use_stack(&key, &keybuf, sizeof keybuf);
+ odp_flow_key_from_flow(&key, &flow);
+
ofpbuf_init(&odp_actions, 32);
nl_msg_put_u32(&odp_actions, ODP_ACTION_ATTR_OUTPUT, odp_port);
- error = dpif_execute(ofproto->dpif, odp_actions.data, odp_actions.size,
+ error = dpif_execute(ofproto->dpif,
+ key.data, key.size,
+ odp_actions.data, odp_actions.size,
packet);
ofpbuf_uninit(&odp_actions);
struct action_xlate_ctx *ctx);
static bool xlate_normal(struct action_xlate_ctx *);
+static void
+commit_odp_actions(struct action_xlate_ctx *ctx)
+{
+ const struct flow *flow = &ctx->flow;
+ struct flow *base = &ctx->base_flow;
+ struct ofpbuf *odp_actions = ctx->odp_actions;
+
+ if (base->tun_id != flow->tun_id) {
+ nl_msg_put_be64(odp_actions, ODP_ACTION_ATTR_SET_TUNNEL, flow->tun_id);
+ base->tun_id = flow->tun_id;
+ }
+
+ if (base->nw_src != flow->nw_src) {
+ nl_msg_put_be32(odp_actions, ODP_ACTION_ATTR_SET_NW_SRC, flow->nw_src);
+ base->nw_src = flow->nw_src;
+ }
+
+ if (base->nw_dst != flow->nw_dst) {
+ nl_msg_put_be32(odp_actions, ODP_ACTION_ATTR_SET_NW_DST, flow->nw_dst);
+ base->nw_dst = flow->nw_dst;
+ }
+
+ if (base->vlan_tci != flow->vlan_tci) {
+ if (!(flow->vlan_tci & htons(VLAN_CFI))) {
+ nl_msg_put_flag(odp_actions, ODP_ACTION_ATTR_STRIP_VLAN);
+ } else {
+ nl_msg_put_be16(odp_actions, ODP_ACTION_ATTR_SET_DL_TCI,
+ flow->vlan_tci & ~htons(VLAN_CFI));
+ }
+ base->vlan_tci = flow->vlan_tci;
+ }
+
+ if (base->tp_src != flow->tp_src) {
+ nl_msg_put_be16(odp_actions, ODP_ACTION_ATTR_SET_TP_SRC, flow->tp_src);
+ base->tp_src = flow->tp_src;
+ }
+
+ if (base->tp_dst != flow->tp_dst) {
+ nl_msg_put_be16(odp_actions, ODP_ACTION_ATTR_SET_TP_DST, flow->tp_dst);
+ base->tp_dst = flow->tp_dst;
+ }
+
+ if (!eth_addr_equals(base->dl_src, flow->dl_src)) {
+ nl_msg_put_unspec(odp_actions, ODP_ACTION_ATTR_SET_DL_SRC,
+ flow->dl_src, ETH_ADDR_LEN);
+ memcpy(base->dl_src, flow->dl_src, ETH_ADDR_LEN);
+ }
+
+ if (!eth_addr_equals(base->dl_dst, flow->dl_dst)) {
+ nl_msg_put_unspec(odp_actions, ODP_ACTION_ATTR_SET_DL_DST,
+ flow->dl_dst, ETH_ADDR_LEN);
+ memcpy(base->dl_dst, flow->dl_dst, ETH_ADDR_LEN);
+ }
+
+ if (ctx->base_priority != ctx->priority) {
+ if (ctx->priority) {
+ nl_msg_put_u32(odp_actions, ODP_ACTION_ATTR_SET_PRIORITY,
+ ctx->priority);
+ } else {
+ nl_msg_put_flag(odp_actions, ODP_ACTION_ATTR_POP_PRIORITY);
+ }
+ ctx->base_priority = ctx->priority;
+ }
+}
+
static void
add_output_action(struct action_xlate_ctx *ctx, uint16_t ofp_port)
{
*/
}
+ commit_odp_actions(ctx);
nl_msg_put_u32(ctx->odp_actions, ODP_ACTION_ATTR_OUTPUT, odp_port);
ctx->nf_output_iface = ofp_port;
}
}
static void
-flood_packets(struct ofproto_dpif *ofproto,
- uint16_t ofp_in_port, ovs_be32 mask,
- uint16_t *nf_output_iface, struct ofpbuf *odp_actions)
+flood_packets(struct action_xlate_ctx *ctx, ovs_be32 mask)
{
struct ofport_dpif *ofport;
- HMAP_FOR_EACH (ofport, up.hmap_node, &ofproto->up.ports) {
+ commit_odp_actions(ctx);
+ HMAP_FOR_EACH (ofport, up.hmap_node, &ctx->ofproto->up.ports) {
uint16_t ofp_port = ofport->up.ofp_port;
- if (ofp_port != ofp_in_port && !(ofport->up.opp.config & mask)) {
- nl_msg_put_u32(odp_actions, ODP_ACTION_ATTR_OUTPUT,
+ if (ofp_port != ctx->flow.in_port && !(ofport->up.opp.config & mask)) {
+ nl_msg_put_u32(ctx->odp_actions, ODP_ACTION_ATTR_OUTPUT,
ofport->odp_port);
}
}
- *nf_output_iface = NF_OUT_FLOOD;
+
+ ctx->nf_output_iface = NF_OUT_FLOOD;
}
static void
xlate_normal(ctx);
break;
case OFPP_FLOOD:
- flood_packets(ctx->ofproto, ctx->flow.in_port, htonl(OFPPC_NO_FLOOD),
- &ctx->nf_output_iface, ctx->odp_actions);
+ flood_packets(ctx, htonl(OFPPC_NO_FLOOD));
break;
case OFPP_ALL:
- flood_packets(ctx->ofproto, ctx->flow.in_port, htonl(0),
- &ctx->nf_output_iface, ctx->odp_actions);
+ flood_packets(ctx, htonl(0));
break;
case OFPP_CONTROLLER:
+ commit_odp_actions(ctx);
nl_msg_put_u64(ctx->odp_actions, ODP_ACTION_ATTR_CONTROLLER, max_len);
break;
case OFPP_LOCAL:
xlate_output_action__(ctx, ntohs(oao->port), ntohs(oao->max_len));
}
-/* If the final ODP action in 'ctx' is "pop priority", drop it, as an
- * optimization, because we're going to add another action that sets the
- * priority immediately after, or because there are no actions following the
- * pop. */
-static void
-remove_pop_action(struct action_xlate_ctx *ctx)
-{
- if (ctx->odp_actions->size == ctx->last_pop_priority) {
- ctx->odp_actions->size -= NLA_ALIGN(NLA_HDRLEN);
- ctx->last_pop_priority = -1;
- }
-}
-
-static void
-add_pop_action(struct action_xlate_ctx *ctx)
-{
- if (ctx->odp_actions->size != ctx->last_pop_priority) {
- nl_msg_put_flag(ctx->odp_actions, ODP_ACTION_ATTR_POP_PRIORITY);
- ctx->last_pop_priority = ctx->odp_actions->size;
- }
-}
-
static void
xlate_enqueue_action(struct action_xlate_ctx *ctx,
const struct ofp_action_enqueue *oae)
{
uint16_t ofp_port, odp_port;
- uint32_t priority;
+ uint32_t ctx_priority, priority;
int error;
error = dpif_queue_to_priority(ctx->ofproto->dpif, ntohl(oae->queue_id),
odp_port = ofp_port_to_odp_port(ofp_port);
/* Add ODP actions. */
- remove_pop_action(ctx);
- nl_msg_put_u32(ctx->odp_actions, ODP_ACTION_ATTR_SET_PRIORITY, priority);
+ ctx_priority = ctx->priority;
+ ctx->priority = priority;
add_output_action(ctx, odp_port);
- add_pop_action(ctx);
+ ctx->priority = ctx_priority;
/* Update NetFlow output port. */
if (ctx->nf_output_iface == NF_OUT_DROP) {
return;
}
- remove_pop_action(ctx);
- nl_msg_put_u32(ctx->odp_actions, ODP_ACTION_ATTR_SET_PRIORITY, priority);
-}
-
-static void
-xlate_set_dl_tci(struct action_xlate_ctx *ctx)
-{
- ovs_be16 tci = ctx->flow.vlan_tci;
- if (!(tci & htons(VLAN_CFI))) {
- nl_msg_put_flag(ctx->odp_actions, ODP_ACTION_ATTR_STRIP_VLAN);
- } else {
- nl_msg_put_be16(ctx->odp_actions, ODP_ACTION_ATTR_SET_DL_TCI,
- tci & ~htons(VLAN_CFI));
- }
+ ctx->priority = priority;
}
struct xlate_reg_state {
ovs_be64 tun_id;
};
-static void
-save_reg_state(const struct action_xlate_ctx *ctx,
- struct xlate_reg_state *state)
-{
- state->vlan_tci = ctx->flow.vlan_tci;
- state->tun_id = ctx->flow.tun_id;
-}
-
-static void
-update_reg_state(struct action_xlate_ctx *ctx,
- const struct xlate_reg_state *state)
-{
- if (ctx->flow.vlan_tci != state->vlan_tci) {
- xlate_set_dl_tci(ctx);
- }
- if (ctx->flow.tun_id != state->tun_id) {
- nl_msg_put_be64(ctx->odp_actions,
- ODP_ACTION_ATTR_SET_TUNNEL, ctx->flow.tun_id);
- }
-}
-
static void
xlate_autopath(struct action_xlate_ctx *ctx,
const struct nx_action_autopath *naa)
const struct nx_action_multipath *nam;
const struct nx_action_autopath *naa;
enum nx_action_subtype subtype = ntohs(nah->subtype);
- struct xlate_reg_state state;
ovs_be64 tun_id;
assert(nah->vendor == htonl(NX_VENDOR_ID));
case NXAST_SET_TUNNEL:
nast = (const struct nx_action_set_tunnel *) nah;
tun_id = htonll(ntohl(nast->tun_id));
- nl_msg_put_be64(ctx->odp_actions, ODP_ACTION_ATTR_SET_TUNNEL, tun_id);
ctx->flow.tun_id = tun_id;
break;
- case NXAST_DROP_SPOOFED_ARP:
- if (ctx->flow.dl_type == htons(ETH_TYPE_ARP)) {
- nl_msg_put_flag(ctx->odp_actions,
- ODP_ACTION_ATTR_DROP_SPOOFED_ARP);
- }
- break;
-
case NXAST_SET_QUEUE:
nasq = (const struct nx_action_set_queue *) nah;
xlate_set_queue_action(ctx, nasq);
break;
case NXAST_POP_QUEUE:
- add_pop_action(ctx);
+ ctx->priority = 0;
break;
case NXAST_REG_MOVE:
- save_reg_state(ctx, &state);
nxm_execute_reg_move((const struct nx_action_reg_move *) nah,
&ctx->flow);
- update_reg_state(ctx, &state);
break;
case NXAST_REG_LOAD:
- save_reg_state(ctx, &state);
nxm_execute_reg_load((const struct nx_action_reg_load *) nah,
&ctx->flow);
- update_reg_state(ctx, &state);
break;
case NXAST_NOTE:
case NXAST_SET_TUNNEL64:
tun_id = ((const struct nx_action_set_tunnel64 *) nah)->tun_id;
- nl_msg_put_be64(ctx->odp_actions, ODP_ACTION_ATTR_SET_TUNNEL, tun_id);
ctx->flow.tun_id = tun_id;
break;
* update the flow key in ctx->flow at the same time. */
case NXAST_SNAT__OBSOLETE:
+ case NXAST_DROP_SPOOFED_ARP__OBSOLETE:
default:
VLOG_DBG_RL(&rl, "unknown Nicira action type %d", (int) subtype);
break;
case OFPAT_SET_VLAN_VID:
ctx->flow.vlan_tci &= ~htons(VLAN_VID_MASK);
ctx->flow.vlan_tci |= ia->vlan_vid.vlan_vid | htons(VLAN_CFI);
- xlate_set_dl_tci(ctx);
break;
case OFPAT_SET_VLAN_PCP:
ctx->flow.vlan_tci &= ~htons(VLAN_PCP_MASK);
ctx->flow.vlan_tci |= htons(
(ia->vlan_pcp.vlan_pcp << VLAN_PCP_SHIFT) | VLAN_CFI);
- xlate_set_dl_tci(ctx);
break;
case OFPAT_STRIP_VLAN:
ctx->flow.vlan_tci = htons(0);
- xlate_set_dl_tci(ctx);
break;
case OFPAT_SET_DL_SRC:
oada = ((struct ofp_action_dl_addr *) ia);
- nl_msg_put_unspec(ctx->odp_actions, ODP_ACTION_ATTR_SET_DL_SRC,
- oada->dl_addr, ETH_ADDR_LEN);
memcpy(ctx->flow.dl_src, oada->dl_addr, ETH_ADDR_LEN);
break;
case OFPAT_SET_DL_DST:
oada = ((struct ofp_action_dl_addr *) ia);
- nl_msg_put_unspec(ctx->odp_actions, ODP_ACTION_ATTR_SET_DL_DST,
- oada->dl_addr, ETH_ADDR_LEN);
memcpy(ctx->flow.dl_dst, oada->dl_addr, ETH_ADDR_LEN);
break;
case OFPAT_SET_NW_SRC:
- nl_msg_put_be32(ctx->odp_actions, ODP_ACTION_ATTR_SET_NW_SRC,
- ia->nw_addr.nw_addr);
ctx->flow.nw_src = ia->nw_addr.nw_addr;
break;
case OFPAT_SET_NW_DST:
- nl_msg_put_be32(ctx->odp_actions, ODP_ACTION_ATTR_SET_NW_DST,
- ia->nw_addr.nw_addr);
ctx->flow.nw_dst = ia->nw_addr.nw_addr;
break;
case OFPAT_SET_NW_TOS:
- nl_msg_put_u8(ctx->odp_actions, ODP_ACTION_ATTR_SET_NW_TOS,
- ia->nw_tos.nw_tos);
ctx->flow.nw_tos = ia->nw_tos.nw_tos;
break;
case OFPAT_SET_TP_SRC:
- nl_msg_put_be16(ctx->odp_actions, ODP_ACTION_ATTR_SET_TP_SRC,
- ia->tp_port.tp_port);
ctx->flow.tp_src = ia->tp_port.tp_port;
break;
case OFPAT_SET_TP_DST:
- nl_msg_put_be16(ctx->odp_actions, ODP_ACTION_ATTR_SET_TP_DST,
- ia->tp_port.tp_port);
ctx->flow.tp_dst = ia->tp_port.tp_port;
break;
ctx->may_set_up_flow = true;
ctx->nf_output_iface = NF_OUT_DROP;
ctx->recurse = 0;
- ctx->last_pop_priority = -1;
+ ctx->priority = 0;
+ ctx->base_priority = 0;
+ ctx->base_flow = ctx->flow;
if (process_special(ctx->ofproto, &ctx->flow, ctx->packet)) {
ctx->may_set_up_flow = false;
do_xlate_actions(in, n_in, ctx);
}
- remove_pop_action(ctx);
-
/* Check with in-band control to see if we're allowed to set up this
* flow. */
if (!connmgr_may_set_up_flow(ctx->ofproto->up.connmgr, &ctx->flow,
error = validate_actions(ofp_actions, n_ofp_actions, flow,
ofproto->max_ports);
if (!error) {
+ struct odputil_keybuf keybuf;
struct action_xlate_ctx ctx;
struct ofpbuf *odp_actions;
+ struct ofpbuf key;
+
+ ofpbuf_use_stack(&key, &keybuf, sizeof keybuf);
+ odp_flow_key_from_flow(&key, flow);
action_xlate_ctx_init(&ctx, ofproto, flow, packet);
odp_actions = xlate_actions(&ctx, ofp_actions, n_ofp_actions);
- dpif_execute(ofproto->dpif, odp_actions->data, odp_actions->size,
- packet);
+ dpif_execute(ofproto->dpif, key.data, key.size,
+ odp_actions->data, odp_actions->size, packet);
ofpbuf_delete(odp_actions);
}
return error;
port_poll,
port_poll_wait,
port_is_lacp_current,
+ NULL, /* rule_choose_table */
rule_alloc,
rule_construct,
rule_destruct,
get_netflow_ids,
set_sflow,
set_cfm,
- get_cfm,
+ get_cfm_fault,
bundle_set,
bundle_remove,
mirror_set,