Commit ccf3c8c3 authored by David Ahern's avatar David Ahern Committed by David S. Miller

net: Add IPv6 support to l3mdev

Add operations to retrieve cached IPv6 dst entry from l3mdev device
and lookup IPv6 source address.
Signed-off-by: default avatarDavid Ahern <dsa@cumulusnetworks.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent af379392
...@@ -19,14 +19,22 @@ ...@@ -19,14 +19,22 @@
* @l3mdev_get_rtable: Get cached IPv4 rtable (dst_entry) for device * @l3mdev_get_rtable: Get cached IPv4 rtable (dst_entry) for device
* *
* @l3mdev_get_saddr: Get source address for a flow * @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 { struct l3mdev_ops {
u32 (*l3mdev_fib_table)(const struct net_device *dev); u32 (*l3mdev_fib_table)(const struct net_device *dev);
/* IPv4 ops */
struct rtable * (*l3mdev_get_rtable)(const struct net_device *dev, struct rtable * (*l3mdev_get_rtable)(const struct net_device *dev,
const struct flowi4 *fl4); const struct flowi4 *fl4);
void (*l3mdev_get_saddr)(struct net_device *dev, void (*l3mdev_get_saddr)(struct net_device *dev,
struct flowi4 *fl4); 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 #ifdef CONFIG_NET_L3_MASTER_DEV
...@@ -123,6 +131,31 @@ static inline void l3mdev_get_saddr(struct net *net, int ifindex, ...@@ -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 #else
static inline int l3mdev_master_ifindex_rcu(struct net_device *dev) 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, ...@@ -171,6 +204,19 @@ static inline void l3mdev_get_saddr(struct net *net, int ifindex,
struct flowi4 *fl4) 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
#endif /* _NET_L3MDEV_H_ */ #endif /* _NET_L3MDEV_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment