Skip to content

Commit

Permalink
ofproto: Meter slowpath action when action upcall meters are configured
Browse files Browse the repository at this point in the history
If a slow path action is a controller action, meter it when the
controller meter is configured.  For other kinds of slow path actions,
meter it when the slowpath meter is configured.

Note, this patch only considers the meters configuration of the
packet's input bridge, which may not be the same bridge that the
action is generated.

Signed-off-by: Andy Zhou <[email protected]>
Acked-by: Jarno Rajahalme <[email protected]>
  • Loading branch information
azhou-nicira committed Apr 28, 2017
1 parent 31b29c2 commit af7535e
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 3 deletions.
34 changes: 31 additions & 3 deletions ofproto/ofproto-dpif-upcall.c
Original file line number Diff line number Diff line change
Expand Up @@ -1025,7 +1025,8 @@ classify_upcall(enum dpif_upcall_type type, const struct nlattr *userdata)
static void
compose_slow_path(struct udpif *udpif, struct xlate_out *xout,
const struct flow *flow, odp_port_t odp_in_port,
struct ofpbuf *buf)
struct ofpbuf *buf, uint32_t slowpath_meter_id,
uint32_t controller_meter_id)
{
union user_action_cookie cookie;
odp_port_t port;
Expand All @@ -1039,8 +1040,28 @@ compose_slow_path(struct udpif *udpif, struct xlate_out *xout,
? ODPP_NONE
: odp_in_port;
pid = dpif_port_get_pid(udpif->dpif, port, flow_hash_5tuple(flow, 0));

size_t offset;
size_t ac_offset;
uint32_t meter_id = xout->slow & SLOW_CONTROLLER ? controller_meter_id
: slowpath_meter_id;

if (meter_id != UINT32_MAX) {
/* If slowpath meter is configured, generate clone(meter, userspace)
* action. */
offset = nl_msg_start_nested(buf, OVS_ACTION_ATTR_SAMPLE);
nl_msg_put_u32(buf, OVS_SAMPLE_ATTR_PROBABILITY, UINT32_MAX);
ac_offset = nl_msg_start_nested(buf, OVS_SAMPLE_ATTR_ACTIONS);
nl_msg_put_u32(buf, OVS_ACTION_ATTR_METER, meter_id);
}

odp_put_userspace_action(pid, &cookie, sizeof cookie.slow_path,
ODPP_NONE, false, buf);

if (meter_id != UINT32_MAX) {
nl_msg_end_nested(buf, ac_offset);
nl_msg_end_nested(buf, offset);
}
}

/* If there is no error, the upcall must be destroyed with upcall_uninit()
Expand Down Expand Up @@ -1143,10 +1164,12 @@ upcall_xlate(struct udpif *udpif, struct upcall *upcall,
ofpbuf_use_const(&upcall->put_actions,
odp_actions->data, odp_actions->size);
} else {
uint32_t smid = upcall->ofproto->up.slowpath_meter_id;
uint32_t cmid = upcall->ofproto->up.controller_meter_id;
/* upcall->put_actions already initialized by upcall_receive(). */
compose_slow_path(udpif, &upcall->xout, upcall->flow,
upcall->flow->in_port.odp_port,
&upcall->put_actions);
&upcall->put_actions, smid, cmid);
}

/* This function is also called for slow-pathed flows. As we are only
Expand Down Expand Up @@ -1972,9 +1995,14 @@ revalidate_ukey__(struct udpif *udpif, const struct udpif_key *ukey,
}

if (xoutp->slow) {
struct ofproto_dpif *ofproto;
ofproto = xlate_lookup_ofproto(udpif->backer, &ctx.flow, NULL);
uint32_t smid = ofproto->up.slowpath_meter_id;
uint32_t cmid = ofproto->up.controller_meter_id;

ofpbuf_clear(odp_actions);
compose_slow_path(udpif, xoutp, &ctx.flow, ctx.flow.in_port.odp_port,
odp_actions);
odp_actions, smid, cmid);
}

if (odp_flow_key_to_mask(ukey->mask, ukey->mask_len, &dp_mask, &ctx.flow)
Expand Down
38 changes: 38 additions & 0 deletions tests/ofproto-dpif.at
Original file line number Diff line number Diff line change
Expand Up @@ -1658,6 +1658,44 @@ NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=14 in_port=1 (via action) data_len
vlan_tci=0x0000,dl_src=50:54:00:00:00:09,dl_dst=50:54:00:00:00:0a,dl_type=0x1234
])

AT_CHECK([ovs-appctl revalidator/purge])
AT_CHECK([ovs-ofctl monitor br0 65534 invalid_ttl -P nxt_packet_in --detach --no-chdir --pidfile 2> ofctl_monitor.log])

dnl Add a controller meter.
AT_CHECK([ovs-ofctl -O OpenFlow13 add-meter br0 'meter=controller pktps stats bands=type=drop rate=1'])

dnl Advance time by 1 second.
AT_CHECK([ovs-appctl time/warp 1000], [0], [ignore])

for i in `seq 1 8`; do
AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x4321)'])
done

AT_CHECK([ovs-appctl dpctl/dump-flows | sed 's/.*\(packets:\)/\1/' | sed 's/used:[[0-9]].[[0-9]]*s/used:0.001s/'], [0], [dnl
flow-dump from non-dpdk interfaces:
packets:7, bytes:98, used:0.001s, actions:sample(sample=100.0%,actions(meter(0),userspace(pid=0,slow_path(controller))))
])

AT_CHECK([ovs-appctl time/warp 1], [0], [ignore])
OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])

dnl Out of 8 packets we sent, one executes the controller action via
dnl miss upcall. Another one got passed the rate limiter.
dnl The rest of packets are blocked by the rate limiter.
AT_CHECK([cat ofctl_monitor.log], [0], [dnl
NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=14 in_port=1 (via action) data_len=14 (unbuffered)
vlan_tci=0x0000,dl_src=50:54:00:00:00:09,dl_dst=50:54:00:00:00:0a,dl_type=0x4321
NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=14 in_port=1 (via action) data_len=14 (unbuffered)
vlan_tci=0x0000,dl_src=50:54:00:00:00:09,dl_dst=50:54:00:00:00:0a,dl_type=0x4321
])
dnl Check meter stats to make it gives the same picture;
dnl 7 packets hit the meter, but 6 packets are dropped by band0.
AT_CHECK([ovs-ofctl -O OpenFlow13 meter-stats br0], [0], [dnl
OFPST_METER reply (OF1.3) (xid=0x2):
meter:controller flow_count:0 packet_in_count:7 byte_in_count:98 duration:1.054s bands:
0: packet_count:6 byte_count:84
])

OVS_VSWITCHD_STOP
AT_CLEANUP

Expand Down

0 comments on commit af7535e

Please sign in to comment.