|
@@ -1623,26 +1623,19 @@ static struct sk_buff *vxlan_na_create(struct sk_buff *request,
|
|
|
static int neigh_reduce(struct net_device *dev, struct sk_buff *skb, __be32 vni)
|
|
|
{
|
|
|
struct vxlan_dev *vxlan = netdev_priv(dev);
|
|
|
- struct nd_msg *msg;
|
|
|
- const struct ipv6hdr *iphdr;
|
|
|
const struct in6_addr *daddr;
|
|
|
- struct neighbour *n;
|
|
|
+ const struct ipv6hdr *iphdr;
|
|
|
struct inet6_dev *in6_dev;
|
|
|
+ struct neighbour *n;
|
|
|
+ struct nd_msg *msg;
|
|
|
|
|
|
in6_dev = __in6_dev_get(dev);
|
|
|
if (!in6_dev)
|
|
|
goto out;
|
|
|
|
|
|
- if (!pskb_may_pull(skb, sizeof(struct ipv6hdr) + sizeof(struct nd_msg)))
|
|
|
- goto out;
|
|
|
-
|
|
|
iphdr = ipv6_hdr(skb);
|
|
|
daddr = &iphdr->daddr;
|
|
|
-
|
|
|
msg = (struct nd_msg *)(iphdr + 1);
|
|
|
- if (msg->icmph.icmp6_code != 0 ||
|
|
|
- msg->icmph.icmp6_type != NDISC_NEIGHBOUR_SOLICITATION)
|
|
|
- goto out;
|
|
|
|
|
|
if (ipv6_addr_loopback(daddr) ||
|
|
|
ipv6_addr_is_multicast(&msg->target))
|
|
@@ -2240,11 +2233,11 @@ tx_error:
|
|
|
static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
|
|
|
{
|
|
|
struct vxlan_dev *vxlan = netdev_priv(dev);
|
|
|
+ struct vxlan_rdst *rdst, *fdst = NULL;
|
|
|
const struct ip_tunnel_info *info;
|
|
|
- struct ethhdr *eth;
|
|
|
bool did_rsc = false;
|
|
|
- struct vxlan_rdst *rdst, *fdst = NULL;
|
|
|
struct vxlan_fdb *f;
|
|
|
+ struct ethhdr *eth;
|
|
|
__be32 vni = 0;
|
|
|
|
|
|
info = skb_tunnel_info(skb);
|
|
@@ -2269,12 +2262,14 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
|
|
|
if (ntohs(eth->h_proto) == ETH_P_ARP)
|
|
|
return arp_reduce(dev, skb, vni);
|
|
|
#if IS_ENABLED(CONFIG_IPV6)
|
|
|
- else if (ntohs(eth->h_proto) == ETH_P_IPV6) {
|
|
|
- struct ipv6hdr *hdr, _hdr;
|
|
|
- if ((hdr = skb_header_pointer(skb,
|
|
|
- skb_network_offset(skb),
|
|
|
- sizeof(_hdr), &_hdr)) &&
|
|
|
- hdr->nexthdr == IPPROTO_ICMPV6)
|
|
|
+ else if (ntohs(eth->h_proto) == ETH_P_IPV6 &&
|
|
|
+ pskb_may_pull(skb, sizeof(struct ipv6hdr) +
|
|
|
+ sizeof(struct nd_msg)) &&
|
|
|
+ ipv6_hdr(skb)->nexthdr == IPPROTO_ICMPV6) {
|
|
|
+ struct nd_msg *m = (struct nd_msg *)(ipv6_hdr(skb) + 1);
|
|
|
+
|
|
|
+ if (m->icmph.icmp6_code == 0 &&
|
|
|
+ m->icmph.icmp6_type == NDISC_NEIGHBOUR_SOLICITATION)
|
|
|
return neigh_reduce(dev, skb, vni);
|
|
|
}
|
|
|
#endif
|