aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/vxlan.c30
-rw-r--r--include/net/addrconf.h1
-rw-r--r--net/ipv6/af_inet6.c1
3 files changed, 30 insertions, 2 deletions
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index faf131e02a72..c833763fe5c4 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -1200,7 +1200,6 @@ static bool route_shortcircuit(struct net_device *dev, struct sk_buff *skb)
1200{ 1200{
1201 struct vxlan_dev *vxlan = netdev_priv(dev); 1201 struct vxlan_dev *vxlan = netdev_priv(dev);
1202 struct neighbour *n; 1202 struct neighbour *n;
1203 struct iphdr *pip;
1204 1203
1205 if (is_multicast_ether_addr(eth_hdr(skb)->h_dest)) 1204 if (is_multicast_ether_addr(eth_hdr(skb)->h_dest))
1206 return false; 1205 return false;
@@ -1208,6 +1207,9 @@ static bool route_shortcircuit(struct net_device *dev, struct sk_buff *skb)
1208 n = NULL; 1207 n = NULL;
1209 switch (ntohs(eth_hdr(skb)->h_proto)) { 1208 switch (ntohs(eth_hdr(skb)->h_proto)) {
1210 case ETH_P_IP: 1209 case ETH_P_IP:
1210 {
1211 struct iphdr *pip;
1212
1211 if (!pskb_may_pull(skb, sizeof(struct iphdr))) 1213 if (!pskb_may_pull(skb, sizeof(struct iphdr)))
1212 return false; 1214 return false;
1213 pip = ip_hdr(skb); 1215 pip = ip_hdr(skb);
@@ -1223,6 +1225,29 @@ static bool route_shortcircuit(struct net_device *dev, struct sk_buff *skb)
1223 } 1225 }
1224 1226
1225 break; 1227 break;
1228 }
1229#if IS_ENABLED(CONFIG_IPV6)
1230 case ETH_P_IPV6:
1231 {
1232 struct ipv6hdr *pip6;
1233
1234 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
1235 return false;
1236 pip6 = ipv6_hdr(skb);
1237 n = neigh_lookup(ipv6_stub->nd_tbl, &pip6->daddr, dev);
1238 if (!n && (vxlan->flags & VXLAN_F_L3MISS)) {
1239 union vxlan_addr ipa = {
1240 .sin6.sin6_addr = pip6->daddr,
1241 .sa.sa_family = AF_INET6,
1242 };
1243
1244 vxlan_ip_miss(dev, &ipa);
1245 return false;
1246 }
1247
1248 break;
1249 }
1250#endif
1226 default: 1251 default:
1227 return false; 1252 return false;
1228 } 1253 }
@@ -1659,7 +1684,8 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
1659 did_rsc = false; 1684 did_rsc = false;
1660 1685
1661 if (f && (f->flags & NTF_ROUTER) && (vxlan->flags & VXLAN_F_RSC) && 1686 if (f && (f->flags & NTF_ROUTER) && (vxlan->flags & VXLAN_F_RSC) &&
1662 ntohs(eth->h_proto) == ETH_P_IP) { 1687 (ntohs(eth->h_proto) == ETH_P_IP ||
1688 ntohs(eth->h_proto) == ETH_P_IPV6)) {
1663 did_rsc = route_shortcircuit(dev, skb); 1689 did_rsc = route_shortcircuit(dev, skb);
1664 if (did_rsc) 1690 if (did_rsc)
1665 f = vxlan_find_mac(vxlan, eth->h_dest); 1691 f = vxlan_find_mac(vxlan, eth->h_dest);
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index 5339cab356bb..bcf957341b62 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -153,6 +153,7 @@ struct ipv6_stub {
153 int (*ipv6_dst_lookup)(struct sock *sk, struct dst_entry **dst, 153 int (*ipv6_dst_lookup)(struct sock *sk, struct dst_entry **dst,
154 struct flowi6 *fl6); 154 struct flowi6 *fl6);
155 void (*udpv6_encap_enable)(void); 155 void (*udpv6_encap_enable)(void);
156 struct neigh_table *nd_tbl;
156}; 157};
157extern const struct ipv6_stub *ipv6_stub __read_mostly; 158extern const struct ipv6_stub *ipv6_stub __read_mostly;
158 159
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 0c9c22f7487a..1996a7c34f73 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -815,6 +815,7 @@ static const struct ipv6_stub ipv6_stub_impl = {
815 .ipv6_sock_mc_drop = ipv6_sock_mc_drop, 815 .ipv6_sock_mc_drop = ipv6_sock_mc_drop,
816 .ipv6_dst_lookup = ip6_dst_lookup, 816 .ipv6_dst_lookup = ip6_dst_lookup,
817 .udpv6_encap_enable = udpv6_encap_enable, 817 .udpv6_encap_enable = udpv6_encap_enable,
818 .nd_tbl = &nd_tbl,
818}; 819};
819 820
820static int __init inet6_init(void) 821static int __init inet6_init(void)