Commit 6853f21f authored by Yuval Mintz's avatar Yuval Mintz Committed by David S. Miller

ipmr,ipmr6: Define a uniform vif_device

The two implementations have almost identical structures - vif_device and
mif_device. As a step toward uniforming the mr_tables, eliminate the
mif_device and relocate the vif_device definition into a new common
header file.

Also, introduce a common initializing function for setting most of the
vif_device fields in a new common source file. This requires modifying
the ipv{4,6] Kconfig and ipv4 makefile as we're introducing a new common
config option - CONFIG_IP_MROUTE_COMMON.
Signed-off-by: default avatarYuval Mintz <yuvalm@mellanox.com>
Acked-by: default avatarNikolay Aleksandrov <nikolay@cumulusnetworks.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a25724b0
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <net/fib_rules.h> #include <net/fib_rules.h>
#include <net/fib_notifier.h> #include <net/fib_notifier.h>
#include <uapi/linux/mroute.h> #include <uapi/linux/mroute.h>
#include <linux/mroute_base.h>
#ifdef CONFIG_IP_MROUTE #ifdef CONFIG_IP_MROUTE
static inline int ip_mroute_opt(int opt) static inline int ip_mroute_opt(int opt)
...@@ -56,18 +57,6 @@ static inline bool ipmr_rule_default(const struct fib_rule *rule) ...@@ -56,18 +57,6 @@ static inline bool ipmr_rule_default(const struct fib_rule *rule)
} }
#endif #endif
struct vif_device {
struct net_device *dev; /* Device we are using */
struct netdev_phys_item_id dev_parent_id; /* Device parent ID */
unsigned long bytes_in,bytes_out;
unsigned long pkt_in,pkt_out; /* Statistics */
unsigned long rate_limit; /* Traffic shaping (NI) */
unsigned char threshold; /* TTL threshold */
unsigned short flags; /* Control flags */
__be32 local,remote; /* Addresses(remote for tunnels)*/
int link; /* Physical interface index */
};
struct vif_entry_notifier_info { struct vif_entry_notifier_info {
struct fib_notifier_info info; struct fib_notifier_info info;
struct net_device *dev; struct net_device *dev;
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <linux/skbuff.h> /* for struct sk_buff_head */ #include <linux/skbuff.h> /* for struct sk_buff_head */
#include <net/net_namespace.h> #include <net/net_namespace.h>
#include <uapi/linux/mroute6.h> #include <uapi/linux/mroute6.h>
#include <linux/mroute_base.h>
#ifdef CONFIG_IPV6_MROUTE #ifdef CONFIG_IPV6_MROUTE
static inline int ip6_mroute_opt(int opt) static inline int ip6_mroute_opt(int opt)
...@@ -62,16 +63,6 @@ static inline void ip6_mr_cleanup(void) ...@@ -62,16 +63,6 @@ static inline void ip6_mr_cleanup(void)
} }
#endif #endif
struct mif_device {
struct net_device *dev; /* Device we are using */
unsigned long bytes_in,bytes_out;
unsigned long pkt_in,pkt_out; /* Statistics */
unsigned long rate_limit; /* Traffic shaping (NI) */
unsigned char threshold; /* TTL threshold */
unsigned short flags; /* Control flags */
int link; /* Physical interface index */
};
#define VIFF_STATIC 0x8000 #define VIFF_STATIC 0x8000
struct mfc6_cache { struct mfc6_cache {
......
#ifndef __LINUX_MROUTE_BASE_H
#define __LINUX_MROUTE_BASE_H
#include <linux/netdevice.h>
/**
* struct vif_device - interface representor for multicast routing
* @dev: network device being used
* @bytes_in: statistic; bytes ingressing
* @bytes_out: statistic; bytes egresing
* @pkt_in: statistic; packets ingressing
* @pkt_out: statistic; packets egressing
* @rate_limit: Traffic shaping (NI)
* @threshold: TTL threshold
* @flags: Control flags
* @link: Physical interface index
* @dev_parent_id: device parent id
* @local: Local address
* @remote: Remote address for tunnels
*/
struct vif_device {
struct net_device *dev;
unsigned long bytes_in, bytes_out;
unsigned long pkt_in, pkt_out;
unsigned long rate_limit;
unsigned char threshold;
unsigned short flags;
int link;
/* Currently only used by ipmr */
struct netdev_phys_item_id dev_parent_id;
__be32 local, remote;
};
#ifdef CONFIG_IP_MROUTE_COMMON
void vif_device_init(struct vif_device *v,
struct net_device *dev,
unsigned long rate_limit,
unsigned char threshold,
unsigned short flags,
unsigned short get_iflink_mask);
#else
static inline void vif_device_init(struct vif_device *v,
struct net_device *dev,
unsigned long rate_limit,
unsigned char threshold,
unsigned short flags,
unsigned short get_iflink_mask)
{
}
#endif
#endif
...@@ -212,9 +212,14 @@ config NET_IPGRE_BROADCAST ...@@ -212,9 +212,14 @@ config NET_IPGRE_BROADCAST
Network), but can be distributed all over the Internet. If you want Network), but can be distributed all over the Internet. If you want
to do that, say Y here and to "IP multicast routing" below. to do that, say Y here and to "IP multicast routing" below.
config IP_MROUTE_COMMON
bool
depends on IP_MROUTE || IPV6_MROUTE
config IP_MROUTE config IP_MROUTE
bool "IP: multicast routing" bool "IP: multicast routing"
depends on IP_MULTICAST depends on IP_MULTICAST
select IP_MROUTE_COMMON
help help
This is used if you want your machine to act as a router for IP This is used if you want your machine to act as a router for IP
packets that have several destination addresses. It is needed on the packets that have several destination addresses. It is needed on the
......
...@@ -20,6 +20,7 @@ obj-$(CONFIG_SYSCTL) += sysctl_net_ipv4.o ...@@ -20,6 +20,7 @@ obj-$(CONFIG_SYSCTL) += sysctl_net_ipv4.o
obj-$(CONFIG_PROC_FS) += proc.o obj-$(CONFIG_PROC_FS) += proc.o
obj-$(CONFIG_IP_MULTIPLE_TABLES) += fib_rules.o obj-$(CONFIG_IP_MULTIPLE_TABLES) += fib_rules.o
obj-$(CONFIG_IP_MROUTE) += ipmr.o obj-$(CONFIG_IP_MROUTE) += ipmr.o
obj-$(CONFIG_IP_MROUTE_COMMON) += ipmr_base.o
obj-$(CONFIG_NET_IPIP) += ipip.o obj-$(CONFIG_NET_IPIP) += ipip.o
gre-y := gre_demux.o gre-y := gre_demux.o
obj-$(CONFIG_NET_FOU) += fou.o obj-$(CONFIG_NET_FOU) += fou.o
......
...@@ -945,6 +945,10 @@ static int vif_add(struct net *net, struct mr_table *mrt, ...@@ -945,6 +945,10 @@ static int vif_add(struct net *net, struct mr_table *mrt,
ip_rt_multicast_event(in_dev); ip_rt_multicast_event(in_dev);
/* Fill in the VIF structures */ /* Fill in the VIF structures */
vif_device_init(v, dev, vifc->vifc_rate_limit,
vifc->vifc_threshold,
vifc->vifc_flags | (!mrtsock ? VIFF_STATIC : 0),
(VIFF_TUNNEL | VIFF_REGISTER));
attr.orig_dev = dev; attr.orig_dev = dev;
if (!switchdev_port_attr_get(dev, &attr)) { if (!switchdev_port_attr_get(dev, &attr)) {
...@@ -953,20 +957,9 @@ static int vif_add(struct net *net, struct mr_table *mrt, ...@@ -953,20 +957,9 @@ static int vif_add(struct net *net, struct mr_table *mrt,
} else { } else {
v->dev_parent_id.id_len = 0; v->dev_parent_id.id_len = 0;
} }
v->rate_limit = vifc->vifc_rate_limit;
v->local = vifc->vifc_lcl_addr.s_addr; v->local = vifc->vifc_lcl_addr.s_addr;
v->remote = vifc->vifc_rmt_addr.s_addr; v->remote = vifc->vifc_rmt_addr.s_addr;
v->flags = vifc->vifc_flags;
if (!mrtsock)
v->flags |= VIFF_STATIC;
v->threshold = vifc->vifc_threshold;
v->bytes_in = 0;
v->bytes_out = 0;
v->pkt_in = 0;
v->pkt_out = 0;
v->link = dev->ifindex;
if (v->flags & (VIFF_TUNNEL | VIFF_REGISTER))
v->link = dev_get_iflink(dev);
/* And finish update writing critical data */ /* And finish update writing critical data */
write_lock_bh(&mrt_lock); write_lock_bh(&mrt_lock);
...@@ -2316,7 +2309,8 @@ static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, ...@@ -2316,7 +2309,8 @@ static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
} }
if (VIF_EXISTS(mrt, c->mfc_parent) && if (VIF_EXISTS(mrt, c->mfc_parent) &&
nla_put_u32(skb, RTA_IIF, mrt->vif_table[c->mfc_parent].dev->ifindex) < 0) nla_put_u32(skb, RTA_IIF,
mrt->vif_table[c->mfc_parent].dev->ifindex) < 0)
return -EMSGSIZE; return -EMSGSIZE;
if (c->mfc_flags & MFC_OFFLOAD) if (c->mfc_flags & MFC_OFFLOAD)
...@@ -2327,6 +2321,8 @@ static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, ...@@ -2327,6 +2321,8 @@ static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) { for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) {
if (VIF_EXISTS(mrt, ct) && c->mfc_un.res.ttls[ct] < 255) { if (VIF_EXISTS(mrt, ct) && c->mfc_un.res.ttls[ct] < 255) {
struct vif_device *vif;
if (!(nhp = nla_reserve_nohdr(skb, sizeof(*nhp)))) { if (!(nhp = nla_reserve_nohdr(skb, sizeof(*nhp)))) {
nla_nest_cancel(skb, mp_attr); nla_nest_cancel(skb, mp_attr);
return -EMSGSIZE; return -EMSGSIZE;
...@@ -2334,7 +2330,8 @@ static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, ...@@ -2334,7 +2330,8 @@ static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
nhp->rtnh_flags = 0; nhp->rtnh_flags = 0;
nhp->rtnh_hops = c->mfc_un.res.ttls[ct]; nhp->rtnh_hops = c->mfc_un.res.ttls[ct];
nhp->rtnh_ifindex = mrt->vif_table[ct].dev->ifindex; vif = &mrt->vif_table[ct];
nhp->rtnh_ifindex = vif->dev->ifindex;
nhp->rtnh_len = sizeof(*nhp); nhp->rtnh_len = sizeof(*nhp);
} }
} }
...@@ -2954,8 +2951,8 @@ struct ipmr_vif_iter { ...@@ -2954,8 +2951,8 @@ struct ipmr_vif_iter {
}; };
static struct vif_device *ipmr_vif_seq_idx(struct net *net, static struct vif_device *ipmr_vif_seq_idx(struct net *net,
struct ipmr_vif_iter *iter, struct ipmr_vif_iter *iter,
loff_t pos) loff_t pos)
{ {
struct mr_table *mrt = iter->mrt; struct mr_table *mrt = iter->mrt;
...@@ -3020,7 +3017,8 @@ static int ipmr_vif_seq_show(struct seq_file *seq, void *v) ...@@ -3020,7 +3017,8 @@ static int ipmr_vif_seq_show(struct seq_file *seq, void *v)
"Interface BytesIn PktsIn BytesOut PktsOut Flags Local Remote\n"); "Interface BytesIn PktsIn BytesOut PktsOut Flags Local Remote\n");
} else { } else {
const struct vif_device *vif = v; const struct vif_device *vif = v;
const char *name = vif->dev ? vif->dev->name : "none"; const char *name = vif->dev ?
vif->dev->name : "none";
seq_printf(seq, seq_printf(seq,
"%2td %-10s %8ld %7ld %8ld %7ld %05X %08X %08X\n", "%2td %-10s %8ld %7ld %8ld %7ld %05X %08X %08X\n",
......
/* Linux multicast routing support
* Common logic shared by IPv4 [ipmr] and IPv6 [ip6mr] implementation
*/
#include <linux/mroute_base.h>
/* Sets everything common except 'dev', since that is done under locking */
void vif_device_init(struct vif_device *v,
struct net_device *dev,
unsigned long rate_limit,
unsigned char threshold,
unsigned short flags,
unsigned short get_iflink_mask)
{
v->dev = NULL;
v->bytes_in = 0;
v->bytes_out = 0;
v->pkt_in = 0;
v->pkt_out = 0;
v->rate_limit = rate_limit;
v->flags = flags;
v->threshold = threshold;
if (v->flags & get_iflink_mask)
v->link = dev_get_iflink(dev);
else
v->link = dev->ifindex;
}
EXPORT_SYMBOL(vif_device_init);
...@@ -278,6 +278,7 @@ config IPV6_SUBTREES ...@@ -278,6 +278,7 @@ config IPV6_SUBTREES
config IPV6_MROUTE config IPV6_MROUTE
bool "IPv6: multicast routing" bool "IPv6: multicast routing"
depends on IPV6 depends on IPV6
select IP_MROUTE_COMMON
---help--- ---help---
Experimental support for IPv6 multicast forwarding. Experimental support for IPv6 multicast forwarding.
If unsure, say N. If unsure, say N.
......
...@@ -62,7 +62,7 @@ struct mr6_table { ...@@ -62,7 +62,7 @@ struct mr6_table {
struct timer_list ipmr_expire_timer; struct timer_list ipmr_expire_timer;
struct list_head mfc6_unres_queue; struct list_head mfc6_unres_queue;
struct list_head mfc6_cache_array[MFC6_LINES]; struct list_head mfc6_cache_array[MFC6_LINES];
struct mif_device vif6_table[MAXMIFS]; struct vif_device vif6_table[MAXMIFS];
int maxvif; int maxvif;
atomic_t cache_resolve_queue_len; atomic_t cache_resolve_queue_len;
bool mroute_do_assert; bool mroute_do_assert;
...@@ -384,7 +384,7 @@ struct ipmr_vif_iter { ...@@ -384,7 +384,7 @@ struct ipmr_vif_iter {
int ct; int ct;
}; };
static struct mif_device *ip6mr_vif_seq_idx(struct net *net, static struct vif_device *ip6mr_vif_seq_idx(struct net *net,
struct ipmr_vif_iter *iter, struct ipmr_vif_iter *iter,
loff_t pos) loff_t pos)
{ {
...@@ -450,7 +450,7 @@ static int ip6mr_vif_seq_show(struct seq_file *seq, void *v) ...@@ -450,7 +450,7 @@ static int ip6mr_vif_seq_show(struct seq_file *seq, void *v)
seq_puts(seq, seq_puts(seq,
"Interface BytesIn PktsIn BytesOut PktsOut Flags\n"); "Interface BytesIn PktsIn BytesOut PktsOut Flags\n");
} else { } else {
const struct mif_device *vif = v; const struct vif_device *vif = v;
const char *name = vif->dev ? vif->dev->name : "none"; const char *name = vif->dev ? vif->dev->name : "none";
seq_printf(seq, seq_printf(seq,
...@@ -776,7 +776,7 @@ static struct net_device *ip6mr_reg_vif(struct net *net, struct mr6_table *mrt) ...@@ -776,7 +776,7 @@ static struct net_device *ip6mr_reg_vif(struct net *net, struct mr6_table *mrt)
static int mif6_delete(struct mr6_table *mrt, int vifi, int notify, static int mif6_delete(struct mr6_table *mrt, int vifi, int notify,
struct list_head *head) struct list_head *head)
{ {
struct mif_device *v; struct vif_device *v;
struct net_device *dev; struct net_device *dev;
struct inet6_dev *in6_dev; struct inet6_dev *in6_dev;
...@@ -929,7 +929,7 @@ static int mif6_add(struct net *net, struct mr6_table *mrt, ...@@ -929,7 +929,7 @@ static int mif6_add(struct net *net, struct mr6_table *mrt,
struct mif6ctl *vifc, int mrtsock) struct mif6ctl *vifc, int mrtsock)
{ {
int vifi = vifc->mif6c_mifi; int vifi = vifc->mif6c_mifi;
struct mif_device *v = &mrt->vif6_table[vifi]; struct vif_device *v = &mrt->vif6_table[vifi];
struct net_device *dev; struct net_device *dev;
struct inet6_dev *in6_dev; struct inet6_dev *in6_dev;
int err; int err;
...@@ -980,21 +980,10 @@ static int mif6_add(struct net *net, struct mr6_table *mrt, ...@@ -980,21 +980,10 @@ static int mif6_add(struct net *net, struct mr6_table *mrt,
dev->ifindex, &in6_dev->cnf); dev->ifindex, &in6_dev->cnf);
} }
/* /* Fill in the VIF structures */
* Fill in the VIF structures vif_device_init(v, dev, vifc->vifc_rate_limit, vifc->vifc_threshold,
*/ vifc->mif6c_flags | (!mrtsock ? VIFF_STATIC : 0),
v->rate_limit = vifc->vifc_rate_limit; MIFF_REGISTER);
v->flags = vifc->mif6c_flags;
if (!mrtsock)
v->flags |= VIFF_STATIC;
v->threshold = vifc->vifc_threshold;
v->bytes_in = 0;
v->bytes_out = 0;
v->pkt_in = 0;
v->pkt_out = 0;
v->link = dev->ifindex;
if (v->flags & MIFF_REGISTER)
v->link = dev_get_iflink(dev);
/* And finish update writing critical data */ /* And finish update writing critical data */
write_lock_bh(&mrt_lock); write_lock_bh(&mrt_lock);
...@@ -1332,7 +1321,7 @@ static int ip6mr_device_event(struct notifier_block *this, ...@@ -1332,7 +1321,7 @@ static int ip6mr_device_event(struct notifier_block *this,
struct net_device *dev = netdev_notifier_info_to_dev(ptr); struct net_device *dev = netdev_notifier_info_to_dev(ptr);
struct net *net = dev_net(dev); struct net *net = dev_net(dev);
struct mr6_table *mrt; struct mr6_table *mrt;
struct mif_device *v; struct vif_device *v;
int ct; int ct;
if (event != NETDEV_UNREGISTER) if (event != NETDEV_UNREGISTER)
...@@ -1873,7 +1862,7 @@ int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg) ...@@ -1873,7 +1862,7 @@ int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg)
{ {
struct sioc_sg_req6 sr; struct sioc_sg_req6 sr;
struct sioc_mif_req6 vr; struct sioc_mif_req6 vr;
struct mif_device *vif; struct vif_device *vif;
struct mfc6_cache *c; struct mfc6_cache *c;
struct net *net = sock_net(sk); struct net *net = sock_net(sk);
struct mr6_table *mrt; struct mr6_table *mrt;
...@@ -1947,7 +1936,7 @@ int ip6mr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg) ...@@ -1947,7 +1936,7 @@ int ip6mr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg)
{ {
struct compat_sioc_sg_req6 sr; struct compat_sioc_sg_req6 sr;
struct compat_sioc_mif_req6 vr; struct compat_sioc_mif_req6 vr;
struct mif_device *vif; struct vif_device *vif;
struct mfc6_cache *c; struct mfc6_cache *c;
struct net *net = sock_net(sk); struct net *net = sock_net(sk);
struct mr6_table *mrt; struct mr6_table *mrt;
...@@ -2018,7 +2007,7 @@ static int ip6mr_forward2(struct net *net, struct mr6_table *mrt, ...@@ -2018,7 +2007,7 @@ static int ip6mr_forward2(struct net *net, struct mr6_table *mrt,
struct sk_buff *skb, struct mfc6_cache *c, int vifi) struct sk_buff *skb, struct mfc6_cache *c, int vifi)
{ {
struct ipv6hdr *ipv6h; struct ipv6hdr *ipv6h;
struct mif_device *vif = &mrt->vif6_table[vifi]; struct vif_device *vif = &mrt->vif6_table[vifi];
struct net_device *dev; struct net_device *dev;
struct dst_entry *dst; struct dst_entry *dst;
struct flowi6 fl6; struct flowi6 fl6;
......
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