diff options
| author | David S. Miller <davem@davemloft.net> | 2015-10-13 14:55:10 +0300 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2015-10-13 14:55:10 +0300 |
| commit | 4b918163aecdec1c5424dcc317907282c58838df (patch) | |
| tree | 44fd3b3e5c0a37c2d5288963806b350383eb150b /include | |
| parent | af3793921d49a772ec1079449219bad4baa0bc96 (diff) | |
| parent | ca254490c8dfdaddb5df8a763774db0f4c5200c3 (diff) | |
| download | linux-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.h | 46 |
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_ */ |
