|
@@ -85,6 +85,15 @@ __ip_vs_dst_check(struct ip_vs_dest *dest, u32 rtos)
|
|
|
return dst;
|
|
|
}
|
|
|
|
|
|
+static inline bool
|
|
|
+__mtu_check_toobig_v6(const struct sk_buff *skb, u32 mtu)
|
|
|
+{
|
|
|
+ if (skb->len > mtu && !skb_is_gso(skb)) {
|
|
|
+ return true; /* Packet size violate MTU size */
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
/* Get route to daddr, update *saddr, optionally bind route to saddr */
|
|
|
static struct rtable *do_output_route4(struct net *net, __be32 daddr,
|
|
|
u32 rtos, int rt_mode, __be32 *saddr)
|
|
@@ -491,7 +500,7 @@ ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
|
|
|
|
|
|
/* MTU checking */
|
|
|
mtu = dst_mtu(&rt->dst);
|
|
|
- if (skb->len > mtu && !skb_is_gso(skb)) {
|
|
|
+ if (__mtu_check_toobig_v6(skb, mtu)) {
|
|
|
if (!skb->dev) {
|
|
|
struct net *net = dev_net(skb_dst(skb)->dev);
|
|
|
|
|
@@ -712,7 +721,7 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
|
|
|
|
|
|
/* MTU checking */
|
|
|
mtu = dst_mtu(&rt->dst);
|
|
|
- if (skb->len > mtu && !skb_is_gso(skb)) {
|
|
|
+ if (__mtu_check_toobig_v6(skb, mtu)) {
|
|
|
if (!skb->dev) {
|
|
|
struct net *net = dev_net(skb_dst(skb)->dev);
|
|
|
|
|
@@ -946,8 +955,8 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
|
|
|
if (skb_dst(skb))
|
|
|
skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu);
|
|
|
|
|
|
- if (mtu < ntohs(old_iph->payload_len) + sizeof(struct ipv6hdr) &&
|
|
|
- !skb_is_gso(skb)) {
|
|
|
+ /* MTU checking: Notice that 'mtu' have been adjusted before hand */
|
|
|
+ if (__mtu_check_toobig_v6(skb, mtu)) {
|
|
|
if (!skb->dev) {
|
|
|
struct net *net = dev_net(skb_dst(skb)->dev);
|
|
|
|
|
@@ -1113,7 +1122,7 @@ ip_vs_dr_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
|
|
|
|
|
|
/* MTU checking */
|
|
|
mtu = dst_mtu(&rt->dst);
|
|
|
- if (skb->len > mtu) {
|
|
|
+ if (__mtu_check_toobig_v6(skb, mtu)) {
|
|
|
if (!skb->dev) {
|
|
|
struct net *net = dev_net(skb_dst(skb)->dev);
|
|
|
|
|
@@ -1349,7 +1358,7 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
|
|
|
|
|
|
/* MTU checking */
|
|
|
mtu = dst_mtu(&rt->dst);
|
|
|
- if (skb->len > mtu && !skb_is_gso(skb)) {
|
|
|
+ if (__mtu_check_toobig_v6(skb, mtu)) {
|
|
|
if (!skb->dev) {
|
|
|
struct net *net = dev_net(skb_dst(skb)->dev);
|
|
|
|