summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2015-10-13 14:55:10 +0300
committerDavid S. Miller <davem@davemloft.net>2015-10-13 14:55:10 +0300
commit4b918163aecdec1c5424dcc317907282c58838df (patch)
tree44fd3b3e5c0a37c2d5288963806b350383eb150b /include
parentaf3793921d49a772ec1079449219bad4baa0bc96 (diff)
parentca254490c8dfdaddb5df8a763774db0f4c5200c3 (diff)
downloadlinux-4b918163aecdec1c5424dcc317907282c58838df.tar.xz
Merge branch 'vrf-ipv6'
David Ahern says: ==================== net: VRF support in IPv6 stack Initial support for VRF in IPv6 stack. Makes IPv6 functionality on par with IPv4 -- ping, tcp client/server and udp client/server all work fine. tcpdump on vrf device and external tap (e.g., host side tap device) shows all packets with proper addresses. IPv6 does not need the source address operation like IPv4. Verified vti6 works properly in my setup as does use of an IPv6 address on the VRF device. v3 - re-based to top of net-next (updates per net namespace changes by Eric) - fixed dst_entry typecasts as requested by Dave - added flags to inet6_rtm_getroute (IPv6 version of deaa0a6a930e) v2 - fixed CONFIG_IPV6 dependency as questioned by Cong - if IPV6 is a module, kbuild ensures VRF is a module - if IPV6 is disabled IPV6 functionality is compiled out of VRF module - addressed comments from Nik over IRC - removed duplicate call to netif_is_l3_master in l3mdev_rt6_dst_by_oif - changed allocation flag from GFP_ATOMIC to GFP_KERNEL since it is init time - added free of rt6i_pcpu - check_ipv6_frame returns false only if packet is NDISC type ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
-rw-r--r--include/net/l3mdev.h46
1 files changed, 46 insertions, 0 deletions
diff --git a/include/net/l3mdev.h b/include/net/l3mdev.h
index 44a19a171104..774d85b2d5d9 100644
--- a/include/net/l3mdev.h
+++ b/include/net/l3mdev.h
@@ -19,14 +19,22 @@
* @l3mdev_get_rtable: Get cached IPv4 rtable (dst_entry) for device
*
* @l3mdev_get_saddr: Get source address for a flow
+ *
+ * @l3mdev_get_rt6_dst: Get cached IPv6 rt6_info (dst_entry) for device
*/
struct l3mdev_ops {
u32 (*l3mdev_fib_table)(const struct net_device *dev);
+
+ /* IPv4 ops */
struct rtable * (*l3mdev_get_rtable)(const struct net_device *dev,
const struct flowi4 *fl4);
void (*l3mdev_get_saddr)(struct net_device *dev,
struct flowi4 *fl4);
+
+ /* IPv6 ops */
+ struct dst_entry * (*l3mdev_get_rt6_dst)(const struct net_device *dev,
+ const struct flowi6 *fl6);
};
#ifdef CONFIG_NET_L3_MASTER_DEV
@@ -123,6 +131,31 @@ static inline void l3mdev_get_saddr(struct net *net, int ifindex,
}
}
+static inline struct dst_entry *l3mdev_get_rt6_dst(const struct net_device *dev,
+ const struct flowi6 *fl6)
+{
+ if (netif_is_l3_master(dev) && dev->l3mdev_ops->l3mdev_get_rt6_dst)
+ return dev->l3mdev_ops->l3mdev_get_rt6_dst(dev, fl6);
+
+ return NULL;
+}
+
+static inline
+struct dst_entry *l3mdev_rt6_dst_by_oif(struct net *net,
+ const struct flowi6 *fl6)
+{
+ struct dst_entry *dst = NULL;
+ struct net_device *dev;
+
+ dev = dev_get_by_index(net, fl6->flowi6_oif);
+ if (dev) {
+ dst = l3mdev_get_rt6_dst(dev, fl6);
+ dev_put(dev);
+ }
+
+ return dst;
+}
+
#else
static inline int l3mdev_master_ifindex_rcu(struct net_device *dev)
@@ -171,6 +204,19 @@ static inline void l3mdev_get_saddr(struct net *net, int ifindex,
struct flowi4 *fl4)
{
}
+
+static inline
+struct dst_entry *l3mdev_get_rt6_dst(const struct net_device *dev,
+ const struct flowi6 *fl6)
+{
+ return NULL;
+}
+static inline
+struct dst_entry *l3mdev_rt6_dst_by_oif(struct net *net,
+ const struct flowi6 *fl6)
+{
+ return NULL;
+}
#endif
#endif /* _NET_L3MDEV_H_ */