mirror of
https://github.com/openvswitch/ovs
synced 2025-08-31 06:15:47 +00:00
netdev-linux: Refactor put police action netlink message
To reuse the code for manipulating police action, move the common initialization code to a function, and change PPS parameters as meter pktps is in unit of packet per second. null_police is redundant because either BPS or PPS, not both, can be configured in one message. So the police passed in to nl_msg_put_act_police can be reused as its rate is zero for PPS, and it also provides the index for police action to be created. Signed-off-by: Jianbo Liu <jianbol@nvidia.com> Acked-by: Eelco Chaudron <echaudro@redhat.com> Signed-off-by: Simon Horman <simon.horman@corigine.com>
This commit is contained in:
@@ -2629,37 +2629,30 @@ nl_msg_act_police_end_nest(struct ofpbuf *request, size_t offset,
|
||||
}
|
||||
|
||||
static void
|
||||
nl_msg_put_act_police(struct ofpbuf *request, struct tc_police police,
|
||||
uint32_t kpkts_rate, uint32_t kpkts_burst)
|
||||
nl_msg_put_act_police(struct ofpbuf *request, struct tc_police *police,
|
||||
uint64_t pkts_rate, uint64_t pkts_burst)
|
||||
{
|
||||
size_t offset, act_offset;
|
||||
uint32_t prio = 0;
|
||||
/* used for PPS, set rate as 0 to act as a single action */
|
||||
struct tc_police null_police;
|
||||
|
||||
memset(&null_police, 0, sizeof null_police);
|
||||
|
||||
if (police.rate.rate) {
|
||||
nl_msg_act_police_start_nest(request, ++prio, &offset, &act_offset);
|
||||
tc_put_rtab(request, TCA_POLICE_RATE, &police.rate);
|
||||
nl_msg_put_unspec(request, TCA_POLICE_TBF, &police, sizeof police);
|
||||
nl_msg_act_police_end_nest(request, offset, act_offset);
|
||||
if (!police->rate.rate && !pkts_rate) {
|
||||
return;
|
||||
}
|
||||
if (kpkts_rate) {
|
||||
unsigned int pkt_burst_ticks, pps_rate, size;
|
||||
nl_msg_act_police_start_nest(request, ++prio, &offset, &act_offset);
|
||||
pps_rate = kpkts_rate * 1000;
|
||||
size = MIN(UINT32_MAX / 1000, kpkts_burst) * 1000;
|
||||
|
||||
nl_msg_act_police_start_nest(request, ++prio, &offset, &act_offset);
|
||||
if (police->rate.rate) {
|
||||
tc_put_rtab(request, TCA_POLICE_RATE, &police->rate);
|
||||
}
|
||||
if (pkts_rate) {
|
||||
uint64_t pkt_burst_ticks;
|
||||
/* Here tc_bytes_to_ticks is used to convert packets rather than bytes
|
||||
to ticks. */
|
||||
pkt_burst_ticks = tc_bytes_to_ticks(pps_rate, size);
|
||||
nl_msg_put_u64(request, TCA_POLICE_PKTRATE64, (uint64_t) pps_rate);
|
||||
nl_msg_put_u64(request, TCA_POLICE_PKTBURST64,
|
||||
(uint64_t) pkt_burst_ticks);
|
||||
nl_msg_put_unspec(request, TCA_POLICE_TBF, &null_police,
|
||||
sizeof null_police);
|
||||
nl_msg_act_police_end_nest(request, offset, act_offset);
|
||||
pkt_burst_ticks = tc_bytes_to_ticks(pkts_rate, pkts_burst);
|
||||
nl_msg_put_u64(request, TCA_POLICE_PKTRATE64, pkts_rate);
|
||||
nl_msg_put_u64(request, TCA_POLICE_PKTBURST64, pkt_burst_ticks);
|
||||
}
|
||||
nl_msg_put_unspec(request, TCA_POLICE_TBF, police, sizeof *police);
|
||||
nl_msg_act_police_end_nest(request, offset, act_offset);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -2692,7 +2685,8 @@ tc_add_matchall_policer(struct netdev *netdev, uint32_t kbits_rate,
|
||||
nl_msg_put_string(&request, TCA_KIND, "matchall");
|
||||
basic_offset = nl_msg_start_nested(&request, TCA_OPTIONS);
|
||||
action_offset = nl_msg_start_nested(&request, TCA_MATCHALL_ACT);
|
||||
nl_msg_put_act_police(&request, pol_act, kpkts_rate, kpkts_burst);
|
||||
nl_msg_put_act_police(&request, &pol_act, kpkts_rate * 1000,
|
||||
kpkts_burst * 1000);
|
||||
nl_msg_end_nested(&request, action_offset);
|
||||
nl_msg_end_nested(&request, basic_offset);
|
||||
|
||||
@@ -5599,6 +5593,29 @@ netdev_linux_tc_make_request(const struct netdev *netdev, int type,
|
||||
return tc_make_request(ifindex, type, flags, request);
|
||||
}
|
||||
|
||||
static void
|
||||
tc_policer_init(struct tc_police *tc_police, uint64_t kbits_rate,
|
||||
uint64_t kbits_burst)
|
||||
{
|
||||
int mtu = 65535;
|
||||
|
||||
memset(tc_police, 0, sizeof *tc_police);
|
||||
|
||||
tc_police->action = TC_POLICE_SHOT;
|
||||
tc_police->mtu = mtu;
|
||||
tc_fill_rate(&tc_police->rate, kbits_rate * 1000 / 8, mtu);
|
||||
|
||||
/* The following appears wrong in one way: In networking a kilobit is
|
||||
* usually 1000 bits but this uses 1024 bits.
|
||||
*
|
||||
* However if you "fix" those problems then "tc filter show ..." shows
|
||||
* "125000b", meaning 125,000 bits, when OVS configures it for 1000 kbit ==
|
||||
* 1,000,000 bits, whereas this actually ends up doing the right thing from
|
||||
* tc's point of view. Whatever. */
|
||||
tc_police->burst = tc_bytes_to_ticks(
|
||||
tc_police->rate.rate, kbits_burst * 1024 / 8);
|
||||
}
|
||||
|
||||
/* Adds a policer to 'netdev' with a rate of 'kbits_rate' and a burst size
|
||||
* of 'kbits_burst', with a rate of 'kpkts_rate' and a burst size of
|
||||
* 'kpkts_burst'.
|
||||
@@ -5623,22 +5640,7 @@ tc_add_policer(struct netdev *netdev, uint32_t kbits_rate,
|
||||
struct ofpbuf request;
|
||||
struct tcmsg *tcmsg;
|
||||
int error;
|
||||
int mtu = 65535;
|
||||
|
||||
memset(&tc_police, 0, sizeof tc_police);
|
||||
tc_police.action = TC_POLICE_SHOT;
|
||||
tc_police.mtu = mtu;
|
||||
tc_fill_rate(&tc_police.rate, ((uint64_t) kbits_rate * 1000)/8, mtu);
|
||||
|
||||
/* The following appears wrong in one way: In networking a kilobit is
|
||||
* usually 1000 bits but this uses 1024 bits.
|
||||
*
|
||||
* However if you "fix" those problems then "tc filter show ..." shows
|
||||
* "125000b", meaning 125,000 bits, when OVS configures it for 1000 kbit ==
|
||||
* 1,000,000 bits, whereas this actually ends up doing the right thing from
|
||||
* tc's point of view. Whatever. */
|
||||
tc_police.burst = tc_bytes_to_ticks(
|
||||
tc_police.rate.rate, MIN(UINT32_MAX / 1024, kbits_burst) * 1024 / 8);
|
||||
tcmsg = netdev_linux_tc_make_request(netdev, RTM_NEWTFILTER,
|
||||
NLM_F_EXCL | NLM_F_CREATE, &request);
|
||||
if (!tcmsg) {
|
||||
@@ -5648,9 +5650,12 @@ tc_add_policer(struct netdev *netdev, uint32_t kbits_rate,
|
||||
tcmsg->tcm_info = tc_make_handle(49,
|
||||
(OVS_FORCE uint16_t) htons(ETH_P_ALL));
|
||||
nl_msg_put_string(&request, TCA_KIND, "basic");
|
||||
|
||||
basic_offset = nl_msg_start_nested(&request, TCA_OPTIONS);
|
||||
police_offset = nl_msg_start_nested(&request, TCA_BASIC_ACT);
|
||||
nl_msg_put_act_police(&request, tc_police, kpkts_rate, kpkts_burst);
|
||||
tc_policer_init(&tc_police, kbits_rate, kbits_burst);
|
||||
nl_msg_put_act_police(&request, &tc_police, kpkts_rate * 1000ULL,
|
||||
kpkts_burst * 1000ULL);
|
||||
nl_msg_end_nested(&request, police_offset);
|
||||
nl_msg_end_nested(&request, basic_offset);
|
||||
|
||||
|
Reference in New Issue
Block a user