Export an encap_err_lookup() operation to match an ICMP error against a valid VNI.
Unified · Split
| @@ -1552,6 +1552,34 @@ drop: · 1551 unmodified lines | ||
| 1552 | 1552 | return 0; |
| 1553 | 1553 | } |
| 1554 | 1554 | |
| 1555 | +/* Callback from net/ipv{4,6}/udp.c to check that we have a VNI for errors */ | |
| 1556 | +static int vxlan_err_lookup(struct sock *sk, struct sk_buff *skb) | |
| 1557 | +{ | |
| 1558 | + struct vxlan_dev *vxlan; | |
| 1559 | + struct vxlan_sock *vs; | |
| 1560 | + struct vxlanhdr *hdr; | |
| 1561 | + __be32 vni; | |
| 1562 | + | |
| 1563 | + if (skb->len < VXLAN_HLEN) | |
| 1564 | + return -EINVAL; | |
| 1565 | + | |
| 1566 | + hdr = vxlan_hdr(skb); | |
| 1567 | + | |
| 1568 | + if (!(hdr->vx_flags & VXLAN_HF_VNI)) | |
| 1569 | + return -EINVAL; | |
| 1570 | + | |
| 1571 | + vs = rcu_dereference_sk_user_data(sk); | |
| 1572 | + if (!vs) | |
| 1573 | + return -ENOENT; | |
| 1574 | + | |
| 1575 | + vni = vxlan_vni(hdr->vx_vni); | |
| 1576 | + vxlan = vxlan_vs_find_vni(vs, skb->dev->ifindex, vni); | |
| 1577 | + if (!vxlan) | |
| 1578 | + return -ENOENT; | |
| 1579 | + | |
| 1580 | + return 0; | |
| 1581 | +} | |
| 1582 | + | |
| 1555 | 1583 | static int arp_reduce(struct net_device *dev, struct sk_buff *skb, __be32 vni) |
| 1556 | 1584 | { |
| 1557 | 1585 | struct vxlan_dev *vxlan = netdev_priv(dev); |
| @@ -2948,6 +2976,7 @@ static struct vxlan_sock *vxlan_socket_create(struct net *net, bool ipv6, · 1390 unmodified lines | ||
| 2948 | 2976 | tunnel_cfg.sk_user_data = vs; |
| 2949 | 2977 | tunnel_cfg.encap_type = 1; |
| 2950 | 2978 | tunnel_cfg.encap_rcv = vxlan_rcv; |
| 2979 | + tunnel_cfg.encap_err_lookup = vxlan_err_lookup; | |
| 2951 | 2980 | tunnel_cfg.encap_destroy = NULL; |
| 2952 | 2981 | tunnel_cfg.gro_receive = vxlan_gro_receive; |
| 2953 | 2982 | tunnel_cfg.gro_complete = vxlan_gro_complete; |