aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'net/xfrm/xfrm_interface.c')
-rw-r--r--net/xfrm/xfrm_interface.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/net/xfrm/xfrm_interface.c b/net/xfrm/xfrm_interface.c
index 6cc9f6e2dd2b..3c642328a117 100644
--- a/net/xfrm/xfrm_interface.c
+++ b/net/xfrm/xfrm_interface.c
@@ -300,16 +300,22 @@ xfrmi_xmit2(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)
300 if (mtu < IPV6_MIN_MTU) 300 if (mtu < IPV6_MIN_MTU)
301 mtu = IPV6_MIN_MTU; 301 mtu = IPV6_MIN_MTU;
302 302
303 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); 303 if (skb->len > 1280)
304 icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
305 else
306 goto xmit;
304 } else { 307 } else {
305 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, 308 if (!(ip_hdr(skb)->frag_off & htons(IP_DF)))
306 htonl(mtu)); 309 goto xmit;
310 icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
311 htonl(mtu));
307 } 312 }
308 313
309 dst_release(dst); 314 dst_release(dst);
310 return -EMSGSIZE; 315 return -EMSGSIZE;
311 } 316 }
312 317
318xmit:
313 xfrmi_scrub_packet(skb, !net_eq(xi->net, dev_net(dev))); 319 xfrmi_scrub_packet(skb, !net_eq(xi->net, dev_net(dev)));
314 skb_dst_set(skb, dst); 320 skb_dst_set(skb, dst);
315 skb->dev = tdev; 321 skb->dev = tdev;
@@ -659,11 +665,16 @@ static int xfrmi_newlink(struct net *src_net, struct net_device *dev,
659 struct netlink_ext_ack *extack) 665 struct netlink_ext_ack *extack)
660{ 666{
661 struct net *net = dev_net(dev); 667 struct net *net = dev_net(dev);
662 struct xfrm_if_parms p; 668 struct xfrm_if_parms p = {};
663 struct xfrm_if *xi; 669 struct xfrm_if *xi;
664 int err; 670 int err;
665 671
666 xfrmi_netlink_parms(data, &p); 672 xfrmi_netlink_parms(data, &p);
673 if (!p.if_id) {
674 NL_SET_ERR_MSG(extack, "if_id must be non zero");
675 return -EINVAL;
676 }
677
667 xi = xfrmi_locate(net, &p); 678 xi = xfrmi_locate(net, &p);
668 if (xi) 679 if (xi)
669 return -EEXIST; 680 return -EEXIST;
@@ -688,9 +699,14 @@ static int xfrmi_changelink(struct net_device *dev, struct nlattr *tb[],
688{ 699{
689 struct xfrm_if *xi = netdev_priv(dev); 700 struct xfrm_if *xi = netdev_priv(dev);
690 struct net *net = xi->net; 701 struct net *net = xi->net;
691 struct xfrm_if_parms p; 702 struct xfrm_if_parms p = {};
692 703
693 xfrmi_netlink_parms(data, &p); 704 xfrmi_netlink_parms(data, &p);
705 if (!p.if_id) {
706 NL_SET_ERR_MSG(extack, "if_id must be non zero");
707 return -EINVAL;
708 }
709
694 xi = xfrmi_locate(net, &p); 710 xi = xfrmi_locate(net, &p);
695 if (!xi) { 711 if (!xi) {
696 xi = netdev_priv(dev); 712 xi = netdev_priv(dev);