Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Yuval Mintz <yuvalm@mellanox.com>
Acked-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Yuval Mintz and committed by
David S. Miller
6853f21f a25724b0

+117 -63
+1 -12
include/linux/mroute.h
··· 9 9 #include <net/fib_rules.h> 10 10 #include <net/fib_notifier.h> 11 11 #include <uapi/linux/mroute.h> 12 + #include <linux/mroute_base.h> 12 13 13 14 #ifdef CONFIG_IP_MROUTE 14 15 static inline int ip_mroute_opt(int opt) ··· 56 55 return true; 57 56 } 58 57 #endif 59 - 60 - struct vif_device { 61 - struct net_device *dev; /* Device we are using */ 62 - struct netdev_phys_item_id dev_parent_id; /* Device parent ID */ 63 - unsigned long bytes_in,bytes_out; 64 - unsigned long pkt_in,pkt_out; /* Statistics */ 65 - unsigned long rate_limit; /* Traffic shaping (NI) */ 66 - unsigned char threshold; /* TTL threshold */ 67 - unsigned short flags; /* Control flags */ 68 - __be32 local,remote; /* Addresses(remote for tunnels)*/ 69 - int link; /* Physical interface index */ 70 - }; 71 58 72 59 struct vif_entry_notifier_info { 73 60 struct fib_notifier_info info;
+1 -10
include/linux/mroute6.h
··· 7 7 #include <linux/skbuff.h> /* for struct sk_buff_head */ 8 8 #include <net/net_namespace.h> 9 9 #include <uapi/linux/mroute6.h> 10 + #include <linux/mroute_base.h> 10 11 11 12 #ifdef CONFIG_IPV6_MROUTE 12 13 static inline int ip6_mroute_opt(int opt) ··· 62 61 return; 63 62 } 64 63 #endif 65 - 66 - struct mif_device { 67 - struct net_device *dev; /* Device we are using */ 68 - unsigned long bytes_in,bytes_out; 69 - unsigned long pkt_in,pkt_out; /* Statistics */ 70 - unsigned long rate_limit; /* Traffic shaping (NI) */ 71 - unsigned char threshold; /* TTL threshold */ 72 - unsigned short flags; /* Control flags */ 73 - int link; /* Physical interface index */ 74 - }; 75 64 76 65 #define VIFF_STATIC 0x8000 77 66
+52
include/linux/mroute_base.h
··· 1 + #ifndef __LINUX_MROUTE_BASE_H 2 + #define __LINUX_MROUTE_BASE_H 3 + 4 + #include <linux/netdevice.h> 5 + 6 + /** 7 + * struct vif_device - interface representor for multicast routing 8 + * @dev: network device being used 9 + * @bytes_in: statistic; bytes ingressing 10 + * @bytes_out: statistic; bytes egresing 11 + * @pkt_in: statistic; packets ingressing 12 + * @pkt_out: statistic; packets egressing 13 + * @rate_limit: Traffic shaping (NI) 14 + * @threshold: TTL threshold 15 + * @flags: Control flags 16 + * @link: Physical interface index 17 + * @dev_parent_id: device parent id 18 + * @local: Local address 19 + * @remote: Remote address for tunnels 20 + */ 21 + struct vif_device { 22 + struct net_device *dev; 23 + unsigned long bytes_in, bytes_out; 24 + unsigned long pkt_in, pkt_out; 25 + unsigned long rate_limit; 26 + unsigned char threshold; 27 + unsigned short flags; 28 + int link; 29 + 30 + /* Currently only used by ipmr */ 31 + struct netdev_phys_item_id dev_parent_id; 32 + __be32 local, remote; 33 + }; 34 + 35 + #ifdef CONFIG_IP_MROUTE_COMMON 36 + void vif_device_init(struct vif_device *v, 37 + struct net_device *dev, 38 + unsigned long rate_limit, 39 + unsigned char threshold, 40 + unsigned short flags, 41 + unsigned short get_iflink_mask); 42 + #else 43 + static inline void vif_device_init(struct vif_device *v, 44 + struct net_device *dev, 45 + unsigned long rate_limit, 46 + unsigned char threshold, 47 + unsigned short flags, 48 + unsigned short get_iflink_mask) 49 + { 50 + } 51 + #endif 52 + #endif
+5
net/ipv4/Kconfig
··· 212 212 Network), but can be distributed all over the Internet. If you want 213 213 to do that, say Y here and to "IP multicast routing" below. 214 214 215 + config IP_MROUTE_COMMON 216 + bool 217 + depends on IP_MROUTE || IPV6_MROUTE 218 + 215 219 config IP_MROUTE 216 220 bool "IP: multicast routing" 217 221 depends on IP_MULTICAST 222 + select IP_MROUTE_COMMON 218 223 help 219 224 This is used if you want your machine to act as a router for IP 220 225 packets that have several destination addresses. It is needed on the
+1
net/ipv4/Makefile
··· 20 20 obj-$(CONFIG_PROC_FS) += proc.o 21 21 obj-$(CONFIG_IP_MULTIPLE_TABLES) += fib_rules.o 22 22 obj-$(CONFIG_IP_MROUTE) += ipmr.o 23 + obj-$(CONFIG_IP_MROUTE_COMMON) += ipmr_base.o 23 24 obj-$(CONFIG_NET_IPIP) += ipip.o 24 25 gre-y := gre_demux.o 25 26 obj-$(CONFIG_NET_FOU) += fou.o
+15 -17
net/ipv4/ipmr.c
··· 945 945 ip_rt_multicast_event(in_dev); 946 946 947 947 /* Fill in the VIF structures */ 948 + vif_device_init(v, dev, vifc->vifc_rate_limit, 949 + vifc->vifc_threshold, 950 + vifc->vifc_flags | (!mrtsock ? VIFF_STATIC : 0), 951 + (VIFF_TUNNEL | VIFF_REGISTER)); 948 952 949 953 attr.orig_dev = dev; 950 954 if (!switchdev_port_attr_get(dev, &attr)) { ··· 957 953 } else { 958 954 v->dev_parent_id.id_len = 0; 959 955 } 960 - v->rate_limit = vifc->vifc_rate_limit; 956 + 961 957 v->local = vifc->vifc_lcl_addr.s_addr; 962 958 v->remote = vifc->vifc_rmt_addr.s_addr; 963 - v->flags = vifc->vifc_flags; 964 - if (!mrtsock) 965 - v->flags |= VIFF_STATIC; 966 - v->threshold = vifc->vifc_threshold; 967 - v->bytes_in = 0; 968 - v->bytes_out = 0; 969 - v->pkt_in = 0; 970 - v->pkt_out = 0; 971 - v->link = dev->ifindex; 972 - if (v->flags & (VIFF_TUNNEL | VIFF_REGISTER)) 973 - v->link = dev_get_iflink(dev); 974 959 975 960 /* And finish update writing critical data */ 976 961 write_lock_bh(&mrt_lock); ··· 2309 2316 } 2310 2317 2311 2318 if (VIF_EXISTS(mrt, c->mfc_parent) && 2312 - nla_put_u32(skb, RTA_IIF, mrt->vif_table[c->mfc_parent].dev->ifindex) < 0) 2319 + nla_put_u32(skb, RTA_IIF, 2320 + mrt->vif_table[c->mfc_parent].dev->ifindex) < 0) 2313 2321 return -EMSGSIZE; 2314 2322 2315 2323 if (c->mfc_flags & MFC_OFFLOAD) ··· 2321 2327 2322 2328 for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) { 2323 2329 if (VIF_EXISTS(mrt, ct) && c->mfc_un.res.ttls[ct] < 255) { 2330 + struct vif_device *vif; 2331 + 2324 2332 if (!(nhp = nla_reserve_nohdr(skb, sizeof(*nhp)))) { 2325 2333 nla_nest_cancel(skb, mp_attr); 2326 2334 return -EMSGSIZE; ··· 2330 2334 2331 2335 nhp->rtnh_flags = 0; 2332 2336 nhp->rtnh_hops = c->mfc_un.res.ttls[ct]; 2333 - nhp->rtnh_ifindex = mrt->vif_table[ct].dev->ifindex; 2337 + vif = &mrt->vif_table[ct]; 2338 + nhp->rtnh_ifindex = vif->dev->ifindex; 2334 2339 nhp->rtnh_len = sizeof(*nhp); 2335 2340 } 2336 2341 } ··· 2951 2954 }; 2952 2955 2953 2956 static struct vif_device *ipmr_vif_seq_idx(struct net *net, 2954 - struct ipmr_vif_iter *iter, 2955 - loff_t pos) 2957 + struct ipmr_vif_iter *iter, 2958 + loff_t pos) 2956 2959 { 2957 2960 struct mr_table *mrt = iter->mrt; 2958 2961 ··· 3017 3020 "Interface BytesIn PktsIn BytesOut PktsOut Flags Local Remote\n"); 3018 3021 } else { 3019 3022 const struct vif_device *vif = v; 3020 - const char *name = vif->dev ? vif->dev->name : "none"; 3023 + const char *name = vif->dev ? 3024 + vif->dev->name : "none"; 3021 3025 3022 3026 seq_printf(seq, 3023 3027 "%2td %-10s %8ld %7ld %8ld %7ld %05X %08X %08X\n",
+28
net/ipv4/ipmr_base.c
··· 1 + /* Linux multicast routing support 2 + * Common logic shared by IPv4 [ipmr] and IPv6 [ip6mr] implementation 3 + */ 4 + 5 + #include <linux/mroute_base.h> 6 + 7 + /* Sets everything common except 'dev', since that is done under locking */ 8 + void vif_device_init(struct vif_device *v, 9 + struct net_device *dev, 10 + unsigned long rate_limit, 11 + unsigned char threshold, 12 + unsigned short flags, 13 + unsigned short get_iflink_mask) 14 + { 15 + v->dev = NULL; 16 + v->bytes_in = 0; 17 + v->bytes_out = 0; 18 + v->pkt_in = 0; 19 + v->pkt_out = 0; 20 + v->rate_limit = rate_limit; 21 + v->flags = flags; 22 + v->threshold = threshold; 23 + if (v->flags & get_iflink_mask) 24 + v->link = dev_get_iflink(dev); 25 + else 26 + v->link = dev->ifindex; 27 + } 28 + EXPORT_SYMBOL(vif_device_init);
+1
net/ipv6/Kconfig
··· 278 278 config IPV6_MROUTE 279 279 bool "IPv6: multicast routing" 280 280 depends on IPV6 281 + select IP_MROUTE_COMMON 281 282 ---help--- 282 283 Experimental support for IPv6 multicast forwarding. 283 284 If unsure, say N.
+13 -24
net/ipv6/ip6mr.c
··· 62 62 struct timer_list ipmr_expire_timer; 63 63 struct list_head mfc6_unres_queue; 64 64 struct list_head mfc6_cache_array[MFC6_LINES]; 65 - struct mif_device vif6_table[MAXMIFS]; 65 + struct vif_device vif6_table[MAXMIFS]; 66 66 int maxvif; 67 67 atomic_t cache_resolve_queue_len; 68 68 bool mroute_do_assert; ··· 384 384 int ct; 385 385 }; 386 386 387 - static struct mif_device *ip6mr_vif_seq_idx(struct net *net, 387 + static struct vif_device *ip6mr_vif_seq_idx(struct net *net, 388 388 struct ipmr_vif_iter *iter, 389 389 loff_t pos) 390 390 { ··· 450 450 seq_puts(seq, 451 451 "Interface BytesIn PktsIn BytesOut PktsOut Flags\n"); 452 452 } else { 453 - const struct mif_device *vif = v; 453 + const struct vif_device *vif = v; 454 454 const char *name = vif->dev ? vif->dev->name : "none"; 455 455 456 456 seq_printf(seq, ··· 776 776 static int mif6_delete(struct mr6_table *mrt, int vifi, int notify, 777 777 struct list_head *head) 778 778 { 779 - struct mif_device *v; 779 + struct vif_device *v; 780 780 struct net_device *dev; 781 781 struct inet6_dev *in6_dev; 782 782 ··· 929 929 struct mif6ctl *vifc, int mrtsock) 930 930 { 931 931 int vifi = vifc->mif6c_mifi; 932 - struct mif_device *v = &mrt->vif6_table[vifi]; 932 + struct vif_device *v = &mrt->vif6_table[vifi]; 933 933 struct net_device *dev; 934 934 struct inet6_dev *in6_dev; 935 935 int err; ··· 980 980 dev->ifindex, &in6_dev->cnf); 981 981 } 982 982 983 - /* 984 - * Fill in the VIF structures 985 - */ 986 - v->rate_limit = vifc->vifc_rate_limit; 987 - v->flags = vifc->mif6c_flags; 988 - if (!mrtsock) 989 - v->flags |= VIFF_STATIC; 990 - v->threshold = vifc->vifc_threshold; 991 - v->bytes_in = 0; 992 - v->bytes_out = 0; 993 - v->pkt_in = 0; 994 - v->pkt_out = 0; 995 - v->link = dev->ifindex; 996 - if (v->flags & MIFF_REGISTER) 997 - v->link = dev_get_iflink(dev); 983 + /* Fill in the VIF structures */ 984 + vif_device_init(v, dev, vifc->vifc_rate_limit, vifc->vifc_threshold, 985 + vifc->mif6c_flags | (!mrtsock ? VIFF_STATIC : 0), 986 + MIFF_REGISTER); 998 987 999 988 /* And finish update writing critical data */ 1000 989 write_lock_bh(&mrt_lock); ··· 1321 1332 struct net_device *dev = netdev_notifier_info_to_dev(ptr); 1322 1333 struct net *net = dev_net(dev); 1323 1334 struct mr6_table *mrt; 1324 - struct mif_device *v; 1335 + struct vif_device *v; 1325 1336 int ct; 1326 1337 1327 1338 if (event != NETDEV_UNREGISTER) ··· 1862 1873 { 1863 1874 struct sioc_sg_req6 sr; 1864 1875 struct sioc_mif_req6 vr; 1865 - struct mif_device *vif; 1876 + struct vif_device *vif; 1866 1877 struct mfc6_cache *c; 1867 1878 struct net *net = sock_net(sk); 1868 1879 struct mr6_table *mrt; ··· 1936 1947 { 1937 1948 struct compat_sioc_sg_req6 sr; 1938 1949 struct compat_sioc_mif_req6 vr; 1939 - struct mif_device *vif; 1950 + struct vif_device *vif; 1940 1951 struct mfc6_cache *c; 1941 1952 struct net *net = sock_net(sk); 1942 1953 struct mr6_table *mrt; ··· 2007 2018 struct sk_buff *skb, struct mfc6_cache *c, int vifi) 2008 2019 { 2009 2020 struct ipv6hdr *ipv6h; 2010 - struct mif_device *vif = &mrt->vif6_table[vifi]; 2021 + struct vif_device *vif = &mrt->vif6_table[vifi]; 2011 2022 struct net_device *dev; 2012 2023 struct dst_entry *dst; 2013 2024 struct flowi6 fl6;