mirror of
https://github.com/openvswitch/ovs
synced 2025-08-31 06:15:47 +00:00
ofp-actions: Add truncate action.
The patch adds a new action to support packet truncation. The new action is formatted as 'output(port=n,max_len=m)', as output to port n, with packet size being MIN(original_size, m). One use case is to enable port mirroring to send smaller packets to the destination port so that only useful packet information is mirrored/copied, saving some performance overhead of copying entire packet payload. Example use case is below as well as shown in the testcases: - Output to port 1 with max_len 100 bytes. - The output packet size on port 1 will be MIN(original_packet_size, 100). # ovs-ofctl add-flow br0 'actions=output(port=1,max_len=100)' - The scope of max_len is limited to output action itself. The following packet size of output:1 and output:2 will be intact. # ovs-ofctl add-flow br0 \ 'actions=output(port=1,max_len=100),output:1,output:2' - The Datapath actions shows: # Datapath actions: trunc(100),1,1,2 Tested-at: https://travis-ci.org/williamtu/ovs-travis/builds/140037134 Signed-off-by: William Tu <u9012063@gmail.com> Acked-by: Pravin B Shelar <pshelar@ovn.org>
This commit is contained in:
committed by
Pravin B Shelar
parent
4c7804f14b
commit
aaca4fe0ce
@@ -60,6 +60,7 @@ struct dp_packet {
|
||||
* or UINT16_MAX. */
|
||||
uint16_t l4_ofs; /* Transport-level header offset,
|
||||
or UINT16_MAX. */
|
||||
uint32_t cutlen; /* length in bytes to cut from the end. */
|
||||
union {
|
||||
struct pkt_metadata md;
|
||||
uint64_t data[DP_PACKET_CONTEXT_SIZE / 8];
|
||||
@@ -494,6 +495,34 @@ dp_packet_set_allocated(struct dp_packet *b, uint16_t s)
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void
|
||||
dp_packet_reset_cutlen(struct dp_packet *b)
|
||||
{
|
||||
b->cutlen = 0;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
dp_packet_set_cutlen(struct dp_packet *b, uint32_t max_len)
|
||||
{
|
||||
if (max_len < ETH_HEADER_LEN) {
|
||||
max_len = ETH_HEADER_LEN;
|
||||
}
|
||||
|
||||
if (max_len >= dp_packet_size(b)) {
|
||||
b->cutlen = 0;
|
||||
} else {
|
||||
b->cutlen = dp_packet_size(b) - max_len;
|
||||
}
|
||||
return b->cutlen;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
dp_packet_get_cutlen(struct dp_packet *b)
|
||||
{
|
||||
/* Always in valid range if user uses dp_packet_set_cutlen. */
|
||||
return b->cutlen;
|
||||
}
|
||||
|
||||
static inline void *
|
||||
dp_packet_data(const struct dp_packet *b)
|
||||
{
|
||||
@@ -567,12 +596,14 @@ enum { NETDEV_MAX_BURST = 32 }; /* Maximum number packets in a batch. */
|
||||
|
||||
struct dp_packet_batch {
|
||||
int count;
|
||||
bool trunc; /* true if the batch needs truncate. */
|
||||
struct dp_packet *packets[NETDEV_MAX_BURST];
|
||||
};
|
||||
|
||||
static inline void dp_packet_batch_init(struct dp_packet_batch *b)
|
||||
{
|
||||
b->count = 0;
|
||||
b->trunc = false;
|
||||
}
|
||||
|
||||
static inline void
|
||||
@@ -585,12 +616,14 @@ dp_packet_batch_clone(struct dp_packet_batch *dst,
|
||||
dst->packets[i] = dp_packet_clone(src->packets[i]);
|
||||
}
|
||||
dst->count = src->count;
|
||||
dst->trunc = src->trunc;
|
||||
}
|
||||
|
||||
static inline void
|
||||
packet_batch_init_packet(struct dp_packet_batch *b, struct dp_packet *p)
|
||||
{
|
||||
b->count = 1;
|
||||
b->trunc = false;
|
||||
b->packets[0] = p;
|
||||
}
|
||||
|
||||
@@ -606,6 +639,38 @@ dp_packet_delete_batch(struct dp_packet_batch *batch, bool may_steal)
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
dp_packet_batch_apply_cutlen(struct dp_packet_batch *pktb)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!pktb->trunc)
|
||||
return;
|
||||
|
||||
for (i = 0; i < pktb->count; i++) {
|
||||
uint32_t cutlen = dp_packet_get_cutlen(pktb->packets[i]);
|
||||
|
||||
dp_packet_set_size(pktb->packets[i],
|
||||
dp_packet_size(pktb->packets[i]) - cutlen);
|
||||
dp_packet_reset_cutlen(pktb->packets[i]);
|
||||
}
|
||||
pktb->trunc = false;
|
||||
}
|
||||
|
||||
static inline void
|
||||
dp_packet_batch_reset_cutlen(struct dp_packet_batch *pktb)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!pktb->trunc)
|
||||
return;
|
||||
|
||||
pktb->trunc = false;
|
||||
for (i = 0; i < pktb->count; i++) {
|
||||
dp_packet_reset_cutlen(pktb->packets[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user