Skip to content

Adding support for setting IP_TOS/IPV6_TCLASS as a socket option#3300

Closed
aredmon85 wants to merge 2 commits intoosrg:masterfrom
aredmon85:feature/ip-tos-socket-option
Closed

Adding support for setting IP_TOS/IPV6_TCLASS as a socket option#3300
aredmon85 wants to merge 2 commits intoosrg:masterfrom
aredmon85:feature/ip-tos-socket-option

Conversation

@aredmon85
Copy link
Contributor

This pull request adds support for configuring IP_TOS/IPV6_TCLASS.

This pull request allows alignment with RFC 2474 and RFC 4594, which both define CS6 as the DiffServ class selector for network control traffic. DSCP class CS6 is widely used to ensure BGP packets are scheduled above most other traffic via high priority TX queues. Using this class with BGP has been widely adopted by several popular closed implementations, including Arista's EOS and Juniper's Junos. (Open source example in FRR).

To support backwards compatibility, the default value used by the operating system is not altered. CS6 (or any other value the operator desires) can be configured optionally under the transport configuration section.

Tested both IPv4 and IPv6 in Ubuntu 24.04 and against Arista EOS:

Example configuration

[neighbors.transport.config]
  local-address = "192.168.1.236"
  remote-port   = 179
  ip-tos        = 192  # CS6 (DSCP 48)

[neighbors.transport.config]
  local-address = "2001:1985::2"
  remote-port   = 179
  ip-tos        = 192  # CS6 (DSCP 48)

Packet capture validation

The following tcpdump output confirms that the configured ip-tos = 192
(CS6 / DSCP 48) is applied to both IPv4 and IPv6 BGP TCP sessions.

IPv4 BGP Keepalive exchange

10:47:24.058716 IP (tos 0xc0, ttl 1, id 59767, offset 0, flags [DF], proto TCP (6), length 71)
    192.168.1.200.179 > 192.168.1.236.42661: Flags [P.], cksum 0x0758 (correct), seq 19:38, ack 20, win 114, options [nop,nop,TS val 1065424848 ecr 450027807], length 19: BGP
        Keepalive Message (4), length: 19
10:47:24.060370 IP (tos 0xc0, ttl 1, id 10305, offset 0, flags [DF], proto TCP (6), length 71)
    192.168.1.236.42661 > 192.168.1.200.179: Flags [P.], cksum 0xfa08 (correct), seq 20:39, ack 38, win 502, options [nop,nop,TS val 450030807 ecr 1065424848], length 19: BGP
        Keepalive Message (4), length: 19

IPv6 BGP Keepalive exchange

10:47:21.015524 IP6 (class 0xc0, flowlabel 0xac27c, hlim 1, next-header TCP (6) payload length: 32)
    2001:1985::2.44377 > 2001:1985::1.179: Flags [.], cksum 0x6ad6 (correct), seq 1, ack 19, win 507, options [nop,nop,TS val 3875133311 ecr 1065424087], length 0
10:47:21.017017 IP6 (class 0xc0, flowlabel 0xac27c, hlim 1, next-header TCP (6) payload length: 51)
    2001:1985::2.44377 > 2001:1985::1.179: Flags [P.], cksum 0x66a6 (correct), seq 1:20, ack 19, win 507, options [nop,nop,TS val 3875133313 ecr 1065424087], length 19: BGP
        Keepalive Message (4), length: 19

@fujita
Copy link
Member

fujita commented Jan 18, 2026

You changed gobgp.pb.go and bgp_configs.go by hand?
If so, you can't. They are generated by definition files. Please see tools directory.

@aredmon85
Copy link
Contributor Author

You changed gobgp.pb.go and bgp_configs.go by hand? If so, you can't. They are generated by definition files. Please see tools directory.

Understood, believe this is fixed - regenerated gobgp.pb.go and bgp_configs.go via definition files.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request adds support for configuring the IP_TOS (IPv4 Type of Service) and IPV6_TCLASS (IPv6 Traffic Class) socket options for BGP TCP connections. This feature allows operators to set DSCP values like CS6 (value 192) to ensure BGP control traffic receives proper priority treatment in the network, aligning with RFC 2474 and RFC 4594 standards.

Changes:

  • Added ip-tos configuration parameter to transport config supporting both IPv4 and IPv6
  • Implemented platform-specific socket option handling across Linux, Darwin, BSD variants, OpenBSD, Windows, and stub platforms
  • Updated YANG schema, protobuf definitions, and configuration structures to support the new field

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tools/pyang_plugins/gobgp.yang Added ip-tos leaf to transport config augmentation
proto/api/gobgp.proto Added ip_tos field to Transport message
api/gobgp.pb.go Generated protobuf code for ip_tos field
pkg/config/oc/bgp_configs.go Added IpTos field to TransportConfig struct with equality check
pkg/config/oc/util.go Added IpTos conversion in peer and peer group API mappings
pkg/server/grpc_server.go Added IpTos conversion from API to config structures
pkg/server/fsm.go Integrated TOS setting in connection initialization and dialer control
internal/pkg/netutils/utils.go Added setSockOptIpTos helper function for IP_TOS/IPV6_TCLASS
internal/pkg/netutils/sockopt_linux.go Implemented SetIPTOSSockopt and added TOS to DialerControl
internal/pkg/netutils/sockopt_darwin.go Implemented SetIpTOSSockopt for macOS
internal/pkg/netutils/sockopt_bsd.go Implemented SetIpTOSSockopt for BSD variants
internal/pkg/netutils/sockopt_openbsd.go Implemented SetIPTOSSockopt and added TOS to DialerControl
internal/pkg/netutils/sockopt_windows.go Added SetIPTOSSockopt returning not-supported error and warning in DialerControl
internal/pkg/netutils/sockopt_stub.go Added SetIpTOSSockopt for unsupported platforms
internal/pkg/netutils/sockopt.go Added SetIPTOSSockopt wrapper but missing TOS handling in DialerControl
docs/sources/configuration.md Added example showing ip-tos configuration usage
Comments suppressed due to low confidence (1)

internal/pkg/netutils/sockopt.go:76

  • Missing TOS handling: The DialerControl function signature now includes a tos parameter, but this implementation doesn't handle it. When tos is non-zero, it should log a warning similar to the other unsupported features, stating that "setting TOS for active connection is not supported".
func DialerControl(logger *slog.Logger, network, address string, c syscall.RawConn, ttl, minTtl uint8, mss uint16, password string, bindInterface string, tos uint8) error {
	if password != "" {
		logger.Warn("setting md5 for active connection is not supported",
			slog.String("Topic", "Peer"),
			slog.String("Key", address),
		)
	}
	if ttl != 0 {
		logger.Warn("setting ttl for active connection is not supported",
			slog.String("Topic", "Peer"),
			slog.String("Key", address),
		)
	}
	if minTtl != 0 {
		logger.Warn("setting min ttl for active connection is not supported",
			slog.String("Topic", "Peer"),
			slog.String("Key", address),
		)
	}
	if mss != 0 {
		logger.Warn("setting MSS for active connection is not supported",
			slog.String("Topic", "Peer"),
			slog.String("Key", address),
		)
	}
	return nil

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 16 out of 16 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@fujita
Copy link
Member

fujita commented Jan 23, 2026

Sorry, can you rebase this against the latest master to resolve the conflicts?

@aredmon85 aredmon85 force-pushed the feature/ip-tos-socket-option branch 2 times, most recently from 449c264 to ae2bd0c Compare January 23, 2026 15:27
@aredmon85 aredmon85 force-pushed the feature/ip-tos-socket-option branch from 68a9aaa to 553d5c1 Compare January 23, 2026 15:35
@aredmon85
Copy link
Contributor Author

Sorry, can you rebase this against the latest master to resolve the conflicts?

Yes, not a problem - done.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 16 out of 16 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@fujita
Copy link
Member

fujita commented Jan 26, 2026

--- a/api/gobgp.pb.go
+++ b/api/gobgp.pb.go
@@ -8453,6 +8453,8 @@ type Transport struct {
        TcpMss        uint32                 `protobuf:"varint,7,opt,name=tcp_mss,json=tcpMss,proto3" json:"tcp_mss,omitempty"`
        BindInterface string                 `protobuf:"bytes,8,opt,name=bind_interface,json=bindInterface,proto3" json:"bind_interface,omitempty"`
        IpTos         uint32                 `protobuf:"varint,9,opt,name=ip_tos,json=ipTos,proto3" json:"ip_tos,omitempty"`
+       unknownFields protoimpl.UnknownFields
+       sizeCache     protoimpl.SizeCache
 }

The above members are missing. I fixed and pushed, thanks.

@fujita fujita closed this Jan 26, 2026
@aredmon85
Copy link
Contributor Author

--- a/api/gobgp.pb.go
+++ b/api/gobgp.pb.go
@@ -8453,6 +8453,8 @@ type Transport struct {
        TcpMss        uint32                 `protobuf:"varint,7,opt,name=tcp_mss,json=tcpMss,proto3" json:"tcp_mss,omitempty"`
        BindInterface string                 `protobuf:"bytes,8,opt,name=bind_interface,json=bindInterface,proto3" json:"bind_interface,omitempty"`
        IpTos         uint32                 `protobuf:"varint,9,opt,name=ip_tos,json=ipTos,proto3" json:"ip_tos,omitempty"`
+       unknownFields protoimpl.UnknownFields
+       sizeCache     protoimpl.SizeCache
 }

The above members are missing. I fixed and pushed, thanks.

Thanks for fixing that and merging, much appreciated

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