Hello Pim,
I did something in the past which extends policer support to L3 sub-interfaces (and beyond), and want to share my thoughts on the accounting change.

What I've Done was to add logical interface support for policers by enabling them on IP arcs (ip4/ip6-unicast) for sub-interfaces, while keeping physical interfaces on device-input. The goal was a unified policer mechanism across L2/L3 interfaces with operational tools.

What I did was,
- Unified Nodes: Reuse existing policer-input/policer-output nodes instead of duplicating for L2/L3. - Arc Selection: In policer_input(), differentiate physical vs. logical interfaces:
- Physical: Enable on device-input.
- Logical: Check IP enablement and enable on ip4-unicast/ip6-unicast arcs. - Features: Register policer on IP arcs ahead of ip-not-enabled for pre-lookup policing. - Extras: CLI/API for mappings, stats, and filtering; smart arc name detection.

From src/vnet/policer/node_funcs.c (feature registrations):
VNET_FEATURE_INIT (policer_input_ip4_node, static) = {
  .arc_name = "ip4-unicast”,
  .node_name = "policer-input”,
  .runs_before = VNET_FEATURES ("ip4-not-enabled”),
};

From src/vnet/policer/policer.c (interface logic):
if (si->type == VNET_SW_INTERFACE_TYPE_HARDWARE) {
vnet_feature_enable_disable ("device-input", "policer-input", sw_if_index, apply, 0, 0);
} else {
  // Enable on IP arcs for logical interfaces
if (ip4_enabled) vnet_feature_enable_disable ("ip4-unicast", "policer-input", sw_if_index, 1, 0, 0);
  // Similar for ip6
}

This enables policing on L3 sub-interfaces via IP arcs, changing length accounting to IP size (excluding L2 headers).



Thanks,
Muhammad




------ Original Message ------
From "Pim van Pelt via lists.fd.io" <[email protected]>
To [email protected]
Cc "Benoit Ganne (bganne) via lists.fd.io" <[email protected]>
Date 1/21/2026 1:01:37 AM
Subject Re: [vpp-dev] improvement: policer on sub-int and L2

Hoi Ben,

On 2026-01-20 00:50, Benoit Ganne (bganne) via lists.fd.io wrote:
I've written https://gerrit.fd.io/r/c/vpp/+/44654 which allows policer
to be attached to L3 sub-interfaces, by applying the policer-input in
front of ip4-unicast/ip6-unicast in the same way that currently
policer-output applies to the ip4-output/ip6-output nodes.

Thanks Pim, I have a couple of comments but maybe this specific one warrants a bit 
more discussions: if I am not mistaken, moving from device-input to ip-unicast 
changes the policer accounting: the policer uses vlib_buffer_length_in_chain() to get 
the packet length which is dependent upon b->current_length and this gets updated 
when me move b->current_data, so the length you get on device-input should take 
into account the ethernet header whereas the length you get on ip-unicast should not.
This is not a big change for big packets, but it can be for smaller ones.
Now, I do not know if we want to take into account the Ethernet header or not 
when policing.
I don't have a strong opinion, but can offer some thoughts -

. Today, we are currently inconsistent in policers:
.. On output, we sit before ip[46]-output (which only works for L3, and uses 
the IP size)
.. For L2, we sit before l2-input (ethernet size)
.. For L2 classifier, we sit before l2-input (ethernet size)
.. For IP4/IP6 classifier, we sit before ip[46]-unicast already (IP size)
.. As an aside: we do not police non-ip (eg MPLS) or ip[46]-multicast in any L3 
policer.
. One thing the gerrit does do, is create consistency: for any(and all) L3 
policers, now the IP size will be used. for any(and all) L2 policers, the 
ethernet size will be used. In return, it does change the contract for 'L3 
input' policers, as you saw

I guess we might standardize on 'always use the whole datagram' approach, and 
retrofit on output and on L3 input the ethernet header, if it exists. Something 
like
  u16 l2_overhead = 0;
  if (!is_l2) {
    vnet_hw_interface_t *hi = vnet_get_sup_hw_interface (vnm, sw_if_index);
    if (hi->hw_class_index == ethernet_hw_interface_class.index)
      l2_overhead = 14;
  }
.. and update vnet_policer_police() to adjust for the l2_overhead? I think it 
would have both consistency, but it would break expectations: the l3 output 
path would now add ethernet overhead, changing the accounting there. If we do 
nothing, the L3 input path would now drop ethernet overhead, changing the 
accounting there. From my read, one way or another, we will be changing 
something that users might notice.

groet,
Pim
-- Pim van Pelt <[email protected]>
PBVP1-RIPE https://ipng.ch/
-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#26722): https://lists.fd.io/g/vpp-dev/message/26722
Mute This Topic: https://lists.fd.io/mt/117359534/21656
Group Owner: [email protected]
Unsubscribe: https://lists.fd.io/g/vpp-dev/leave/14379924/21656/631435203/xyzzy 
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to