1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2021 Felix Fietkau <nbd@nbd.name>
5 #define KBUILD_MODNAME "foo"
6 #include <uapi/linux/bpf.h>
7 #include <uapi/linux/if_ether.h>
8 #include <uapi/linux/if_packet.h>
9 #include <uapi/linux/ip.h>
10 #include <uapi/linux/ipv6.h>
11 #include <uapi/linux/in.h>
12 #include <uapi/linux/tcp.h>
13 #include <uapi/linux/filter.h>
14 #include <uapi/linux/pkt_cls.h>
18 #include <bpf/bpf_helpers.h>
19 #include <bpf/bpf_endian.h>
20 #include "bpf_skb_utils.h"
22 const volatile static uint32_t mtu
= 1420;
24 static __always_inline
unsigned int
25 optlen(const u_int8_t
*opt
)
27 if (opt
[0] <= TCPOPT_NOP
|| opt
[1] == 0)
33 static __always_inline
void
34 fixup_tcp(struct skb_parser_info
*info
, __u16 mss
)
37 __u32 end
, offset
= info
->offset
+ sizeof(*tcph
);
43 tcph
= skb_parse_tcp(info
);
47 flags
= tcp_flag_byte(tcph
);
48 if (!(flags
& TCPHDR_SYN
))
54 for (i
= 0; i
< 5; i
++) {
58 opt
= skb_ptr(info
->skb
, offset
, 4);
62 offset
+= optlen(opt
);
63 if (opt
[0] != TCPOPT_MSS
|| opt
[1] != TCPOLEN_MSS
)
71 oldmss
= (opt
[2] << 8) | opt
[3];
77 csum_replace2(&tcph
->check
, bpf_htons(oldmss
), bpf_htons(mss
));
81 int mssfix(struct __sk_buff
*skb
)
83 struct skb_parser_info info
;
87 skb_parse_init(&info
, skb
);
88 if (!skb_parse_ethernet(&info
))
91 skb_parse_vlan(&info
);
92 skb_parse_vlan(&info
);
94 if (!skb_parse_ipv4(&info
, 60) && !skb_parse_ipv6(&info
, 60))
97 if (info
.proto
!= IPPROTO_TCP
)
101 mss
-= info
.offset
+ sizeof(struct tcphdr
);
102 fixup_tcp(&info
, mss
);
104 return TC_ACT_UNSPEC
;