diff options
author | Cong Wang <amwang@redhat.com> | 2013-08-31 01:44:34 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-08-31 22:30:00 -0400 |
commit | e15a00aafa4b7953ad717d3cb1ad7acf4ff76945 (patch) | |
tree | 7acce1d228f31755cac9b9d10d8574b48eb89123 /drivers/net/vxlan.c | |
parent | e4c7ed415387cf718ffbec305396c30cee092987 (diff) |
vxlan: add ipv6 route short circuit support
route short circuit only has IPv4 part, this patch adds
the IPv6 part. nd_tbl will be needed.
Cc: David S. Miller <davem@davemloft.net>
Cc: David Stevens <dlstevens@us.ibm.com>
Signed-off-by: Cong Wang <amwang@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/vxlan.c')
-rw-r--r-- | drivers/net/vxlan.c | 30 |
1 files changed, 28 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); |