Skip to content

Feat/pedit helper methods#331

Open
Arshiya2005 wants to merge 3 commits into
florianl:mainfrom
Arshiya2005:feat/pedit-helper-methods
Open

Feat/pedit helper methods#331
Arshiya2005 wants to merge 3 commits into
florianl:mainfrom
Arshiya2005:feat/pedit-helper-methods

Conversation

@Arshiya2005

Copy link
Copy Markdown

Problem

Working with the tc pedit action currently requires callers to manually
compute byte offsets, masks, and shifts for each packet field they want
to rewrite. This is error-prone and requires deep knowledge of packet
header layouts.

Changes

Add full support for the pedit action, including:

  • Core types: Pedit, PeditSel, PeditKey, PeditKeyEx
  • PeditHeaderType and PeditCmd enums for extended key attributes
  • marshal/unmarshal for the pedit netlink message format
  • Wire pedit into the Action struct and kind-dispatch switch so it can be used alongside other actions

High-level helpers that abstract raw byte offset calculations:

  • SetIPv4Src / SetIPv4Dst - rewrite IPv4 source/destination addresses
  • SetEthSrc / SetEthDst - rewrite Ethernet MAC addresses
  • SetSrcPort / SetDstPort / SetUDPSrc / SetUDPDst - rewrite L4 ports
  • AddIPv4TTL - increment or decrement the IPv4 TTL field

Sample TC Rule

tc filter add dev net0 ingress prio 1 handle 101 chain 0 proto ip flower \
  ip_flags nofrag ip_proto udp \
  src_ip 192.0.2.10/32 src_port 1111 \
  dst_ip 192.0.2.20/32 dst_port 2222 \
  action pedit ex \
    munge ip  src   set 10.0.0.1  \
    munge ip  dst   set 10.0.0.2  \
    munge udp sport set 10000     \
    munge udp dport set 20000     \
    munge ip  ttl   add 255       \
  pipe \
  action pedit ex \
    munge eth src set aa:bb:cc:dd:ee:01 \
    munge eth dst set aa:bb:cc:dd:ee:02 \
  pipe \
  action csum iph and udp pipe \
  action mirred egress redirect dev net1

The helpers map directly to munge clauses — each call sets the correct offset, mask, and value internally:

var ipRW tc.Pedit
ipRW.SetIPv4Src(net.ParseIP("10.0.0.1")) // munge ip src set
ipRW.SetIPv4Dst(net.ParseIP("10.0.0.2")) // munge ip dst set

Why

These helpers cover the most common stateless packet rewriting use cases,
following the same pattern established by other action types in this library.
Callers can now use p.SetIPv4Src(ip) instead of constructing raw
PeditKey structs with hardcoded offsets.

Arshiya Gafur Kazi added 3 commits July 2, 2026 12:39
Add support for the tc pedit action, including:
- Core types: Pedit, PeditSel, PeditKey, PeditKeyEx
- PeditHeaderType and PeditCmd enums for extended key attributes
- marshal/unmarshal for the pedit netlink message format

High-level helpers that abstract raw byte offset calculations:
- SetIPv4Src/SetIPv4Dst: rewrite IPv4 source/destination addresses
- SetEthSrc/SetEthDst: rewrite Ethernet MAC addresses
- SetSrcPort/SetDstPort/SetUDPSrc/SetUDPDst: rewrite L4 ports
- AddIPv4TTL: increment or decrement the IPv4 TTL field
Add Pedit *Pedit field to Action, and handle "pedit" in marshalAction
and extractActOptions so callers can use Kind: "pedit" alongside other
action types.
@florianl

Copy link
Copy Markdown
Owner

Hi @Arshiya2005
Thank you for your hard work and contribution on this. I’ll review and get back to you with feedback this weekend.

@florianl florianl left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your work and contribution.

While I support merging the pedit module, I have reservations about the helper functions. They only cover a small subset of functionality and introduce maintenance overhead that falls outside the core scope of this package. Historically, we have avoided adding similar helpers for other TC modules for this exact reason.

Comment thread m_pedit.go
Comment on lines +11 to +14
const (
peditIPProtoTCP = 6
peditIPProtoUDP = 17
)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TCP and UDP should not get redefined here.

Suggested change
const (
peditIPProtoTCP = 6
peditIPProtoUDP = 17
)

Comment thread m_pedit.go
Comment on lines +131 to +137
func (p *Pedit) SetUDPSrc(port uint16) {
p.SetSrcPort(port, peditIPProtoUDP)
}

func (p *Pedit) SetUDPDst(port uint16) {
p.SetDstPort(port, peditIPProtoUDP)
}

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As these helpers are trivial and there are no TCP helpers, this should get removed.

Suggested change
func (p *Pedit) SetUDPSrc(port uint16) {
p.SetSrcPort(port, peditIPProtoUDP)
}
func (p *Pedit) SetUDPDst(port uint16) {
p.SetDstPort(port, peditIPProtoUDP)
}

Comment thread m_pedit.go

func peditProtocolHeaderType(protocol uint8) (PeditHeaderType, bool) {
switch protocol {
case peditIPProtoTCP:

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add IPPROTO_TCP to internal/unix.

Suggested change
case peditIPProtoTCP:
case unix.IPPROTO_TCP:

Comment thread m_pedit.go
switch protocol {
case peditIPProtoTCP:
return PeditHeaderTypeTCP, true
case peditIPProtoUDP:

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add IPPROTO_UDP to internal/unix.

Suggested change
case peditIPProtoUDP:
case unix.IPPROTO_UDP:

Comment thread m_pedit.go
Comment on lines +186 to +188
func peditSwap16(v uint16) uint16 {
return (v << 8) | (v >> 8)
}

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use the existing function endianSwapUint16() instead.

Suggested change
func peditSwap16(v uint16) uint16 {
return (v << 8) | (v >> 8)
}

Comment thread m_pedit.go
err = unmarshalStruct(ad.Bytes(), tcft)
multiError = concatError(multiError, err)
info.Tm = tcft
case tcaPeditKeysEx, tcaPeditPad:

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please implement tcaPeditKeysEx.

Comment thread m_pedit.go
Comment on lines +110 to +113
ip4 := ip.To4()
if ip4 == nil {
return
}

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use the existing helper functions.

Suggested change
ip4 := ip.To4()
if ip4 == nil {
return
}
ip4, err := ipToUint32(ip)

Comment thread m_pedit.go
Comment on lines +121 to +124
ip4 := ip.To4()
if ip4 == nil {
return
}

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use the existing helper functions.

Suggested change
ip4 := ip.To4()
if ip4 == nil {
return
}
ip4, err := ipToUint32(ip)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants