ip6mr.c (f243e5a7859a24d10975afb9a1708cac624ba6f1) ip6mr.c (63159f29be1df7f93563a8a0f78c5e65fc844ed6)
1/*
2 * Linux IPv6 multicast routing support for BSD pim6sd
3 * Based on net/ipv4/ipmr.c.
4 *
5 * (c) 2004 Mickael Hoerdt, <hoerdt@clarinet.u-strasbg.fr>
6 * LSIIT Laboratory, Strasbourg, France
7 * (c) 2004 Jean-Philippe Andriot, <jean-philippe.andriot@6WIND.com>
8 * 6WIND, Paris, France

--- 42 unchanged lines hidden (view full) ---

51#include <net/addrconf.h>
52#include <linux/netfilter_ipv6.h>
53#include <linux/export.h>
54#include <net/ip6_checksum.h>
55#include <linux/netconf.h>
56
57struct mr6_table {
58 struct list_head list;
1/*
2 * Linux IPv6 multicast routing support for BSD pim6sd
3 * Based on net/ipv4/ipmr.c.
4 *
5 * (c) 2004 Mickael Hoerdt, <hoerdt@clarinet.u-strasbg.fr>
6 * LSIIT Laboratory, Strasbourg, France
7 * (c) 2004 Jean-Philippe Andriot, <jean-philippe.andriot@6WIND.com>
8 * 6WIND, Paris, France

--- 42 unchanged lines hidden (view full) ---

51#include <net/addrconf.h>
52#include <linux/netfilter_ipv6.h>
53#include <linux/export.h>
54#include <net/ip6_checksum.h>
55#include <linux/netconf.h>
56
57struct mr6_table {
58 struct list_head list;
59#ifdef CONFIG_NET_NS
60 struct net *net;
61#endif
59 possible_net_t net;
62 u32 id;
63 struct sock *mroute6_sk;
64 struct timer_list ipmr_expire_timer;
65 struct list_head mfc6_unres_queue;
66 struct list_head mfc6_cache_array[MFC6_LINES];
67 struct mif_device vif6_table[MAXMIFS];
68 int maxvif;
69 atomic_t cache_resolve_queue_len;

--- 100 unchanged lines hidden (view full) ---

170 case FR_ACT_PROHIBIT:
171 return -EACCES;
172 case FR_ACT_BLACKHOLE:
173 default:
174 return -EINVAL;
175 }
176
177 mrt = ip6mr_get_table(rule->fr_net, rule->table);
60 u32 id;
61 struct sock *mroute6_sk;
62 struct timer_list ipmr_expire_timer;
63 struct list_head mfc6_unres_queue;
64 struct list_head mfc6_cache_array[MFC6_LINES];
65 struct mif_device vif6_table[MAXMIFS];
66 int maxvif;
67 atomic_t cache_resolve_queue_len;

--- 100 unchanged lines hidden (view full) ---

168 case FR_ACT_PROHIBIT:
169 return -EACCES;
170 case FR_ACT_BLACKHOLE:
171 default:
172 return -EINVAL;
173 }
174
175 mrt = ip6mr_get_table(rule->fr_net, rule->table);
178 if (mrt == NULL)
176 if (!mrt)
179 return -EAGAIN;
180 res->mrt = mrt;
181 return 0;
182}
183
184static int ip6mr_rule_match(struct fib_rule *rule, struct flowi *flp, int flags)
185{
186 return 1;

--- 47 unchanged lines hidden (view full) ---

234
235 ops = fib_rules_register(&ip6mr_rules_ops_template, net);
236 if (IS_ERR(ops))
237 return PTR_ERR(ops);
238
239 INIT_LIST_HEAD(&net->ipv6.mr6_tables);
240
241 mrt = ip6mr_new_table(net, RT6_TABLE_DFLT);
177 return -EAGAIN;
178 res->mrt = mrt;
179 return 0;
180}
181
182static int ip6mr_rule_match(struct fib_rule *rule, struct flowi *flp, int flags)
183{
184 return 1;

--- 47 unchanged lines hidden (view full) ---

232
233 ops = fib_rules_register(&ip6mr_rules_ops_template, net);
234 if (IS_ERR(ops))
235 return PTR_ERR(ops);
236
237 INIT_LIST_HEAD(&net->ipv6.mr6_tables);
238
239 mrt = ip6mr_new_table(net, RT6_TABLE_DFLT);
242 if (mrt == NULL) {
240 if (!mrt) {
243 err = -ENOMEM;
244 goto err1;
245 }
246
247 err = fib_default_rule_add(ops, 0x7fff, RT6_TABLE_DFLT, 0);
248 if (err < 0)
249 goto err2;
250
251 net->ipv6.mr6_rules_ops = ops;
252 return 0;
253
254err2:
241 err = -ENOMEM;
242 goto err1;
243 }
244
245 err = fib_default_rule_add(ops, 0x7fff, RT6_TABLE_DFLT, 0);
246 if (err < 0)
247 goto err2;
248
249 net->ipv6.mr6_rules_ops = ops;
250 return 0;
251
252err2:
255 ip6mr_free_table(mrt);
253 kfree(mrt);
256err1:
257 fib_rules_unregister(ops);
258 return err;
259}
260
261static void __net_exit ip6mr_rules_exit(struct net *net)
262{
263 struct mr6_table *mrt, *next;

--- 42 unchanged lines hidden (view full) ---

306 struct mr6_table *mrt;
307 unsigned int i;
308
309 mrt = ip6mr_get_table(net, id);
310 if (mrt != NULL)
311 return mrt;
312
313 mrt = kzalloc(sizeof(*mrt), GFP_KERNEL);
254err1:
255 fib_rules_unregister(ops);
256 return err;
257}
258
259static void __net_exit ip6mr_rules_exit(struct net *net)
260{
261 struct mr6_table *mrt, *next;

--- 42 unchanged lines hidden (view full) ---

304 struct mr6_table *mrt;
305 unsigned int i;
306
307 mrt = ip6mr_get_table(net, id);
308 if (mrt != NULL)
309 return mrt;
310
311 mrt = kzalloc(sizeof(*mrt), GFP_KERNEL);
314 if (mrt == NULL)
312 if (!mrt)
315 return NULL;
316 mrt->id = id;
317 write_pnet(&mrt->net, net);
318
319 /* Forwarding cache */
320 for (i = 0; i < MFC6_LINES; i++)
321 INIT_LIST_HEAD(&mrt->mfc6_cache_array[i]);
322

--- 82 unchanged lines hidden (view full) ---

405static void *ip6mr_vif_seq_start(struct seq_file *seq, loff_t *pos)
406 __acquires(mrt_lock)
407{
408 struct ipmr_vif_iter *iter = seq->private;
409 struct net *net = seq_file_net(seq);
410 struct mr6_table *mrt;
411
412 mrt = ip6mr_get_table(net, RT6_TABLE_DFLT);
313 return NULL;
314 mrt->id = id;
315 write_pnet(&mrt->net, net);
316
317 /* Forwarding cache */
318 for (i = 0; i < MFC6_LINES; i++)
319 INIT_LIST_HEAD(&mrt->mfc6_cache_array[i]);
320

--- 82 unchanged lines hidden (view full) ---

403static void *ip6mr_vif_seq_start(struct seq_file *seq, loff_t *pos)
404 __acquires(mrt_lock)
405{
406 struct ipmr_vif_iter *iter = seq->private;
407 struct net *net = seq_file_net(seq);
408 struct mr6_table *mrt;
409
410 mrt = ip6mr_get_table(net, RT6_TABLE_DFLT);
413 if (mrt == NULL)
411 if (!mrt)
414 return ERR_PTR(-ENOENT);
415
416 iter->mrt = mrt;
417
418 read_lock(&mrt_lock);
419 return *pos ? ip6mr_vif_seq_idx(net, seq->private, *pos - 1)
420 : SEQ_START_TOKEN;
421}

--- 67 unchanged lines hidden (view full) ---

489
490static void *ipmr_mfc_seq_start(struct seq_file *seq, loff_t *pos)
491{
492 struct ipmr_mfc_iter *it = seq->private;
493 struct net *net = seq_file_net(seq);
494 struct mr6_table *mrt;
495
496 mrt = ip6mr_get_table(net, RT6_TABLE_DFLT);
412 return ERR_PTR(-ENOENT);
413
414 iter->mrt = mrt;
415
416 read_lock(&mrt_lock);
417 return *pos ? ip6mr_vif_seq_idx(net, seq->private, *pos - 1)
418 : SEQ_START_TOKEN;
419}

--- 67 unchanged lines hidden (view full) ---

487
488static void *ipmr_mfc_seq_start(struct seq_file *seq, loff_t *pos)
489{
490 struct ipmr_mfc_iter *it = seq->private;
491 struct net *net = seq_file_net(seq);
492 struct mr6_table *mrt;
493
494 mrt = ip6mr_get_table(net, RT6_TABLE_DFLT);
497 if (mrt == NULL)
495 if (!mrt)
498 return ERR_PTR(-ENOENT);
499
500 it->mrt = mrt;
501 return *pos ? ipmr_mfc_seq_idx(net, seq->private, *pos - 1)
502 : SEQ_START_TOKEN;
503}
504
505static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos)

--- 156 unchanged lines hidden (view full) ---

662
663 read_lock(&mrt_lock);
664 if (reg_vif_num >= 0)
665 reg_dev = mrt->vif6_table[reg_vif_num].dev;
666 if (reg_dev)
667 dev_hold(reg_dev);
668 read_unlock(&mrt_lock);
669
496 return ERR_PTR(-ENOENT);
497
498 it->mrt = mrt;
499 return *pos ? ipmr_mfc_seq_idx(net, seq->private, *pos - 1)
500 : SEQ_START_TOKEN;
501}
502
503static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos)

--- 156 unchanged lines hidden (view full) ---

660
661 read_lock(&mrt_lock);
662 if (reg_vif_num >= 0)
663 reg_dev = mrt->vif6_table[reg_vif_num].dev;
664 if (reg_dev)
665 dev_hold(reg_dev);
666 read_unlock(&mrt_lock);
667
670 if (reg_dev == NULL)
668 if (!reg_dev)
671 goto drop;
672
673 skb->mac_header = skb->network_header;
674 skb_pull(skb, (u8 *)encap - skb->data);
675 skb_reset_network_header(skb);
676 skb->protocol = htons(ETH_P_IPV6);
677 skb->ip_summed = CHECKSUM_NONE;
678

--- 61 unchanged lines hidden (view full) ---

740 char name[IFNAMSIZ];
741
742 if (mrt->id == RT6_TABLE_DFLT)
743 sprintf(name, "pim6reg");
744 else
745 sprintf(name, "pim6reg%u", mrt->id);
746
747 dev = alloc_netdev(0, name, NET_NAME_UNKNOWN, reg_vif_setup);
669 goto drop;
670
671 skb->mac_header = skb->network_header;
672 skb_pull(skb, (u8 *)encap - skb->data);
673 skb_reset_network_header(skb);
674 skb->protocol = htons(ETH_P_IPV6);
675 skb->ip_summed = CHECKSUM_NONE;
676

--- 61 unchanged lines hidden (view full) ---

738 char name[IFNAMSIZ];
739
740 if (mrt->id == RT6_TABLE_DFLT)
741 sprintf(name, "pim6reg");
742 else
743 sprintf(name, "pim6reg%u", mrt->id);
744
745 dev = alloc_netdev(0, name, NET_NAME_UNKNOWN, reg_vif_setup);
748 if (dev == NULL)
746 if (!dev)
749 return NULL;
750
751 dev_net_set(dev, net);
752
753 if (register_netdevice(dev)) {
754 free_netdev(dev);
755 return NULL;
756 }

--- 312 unchanged lines hidden (view full) ---

1069}
1070
1071/*
1072 * Allocate a multicast cache entry
1073 */
1074static struct mfc6_cache *ip6mr_cache_alloc(void)
1075{
1076 struct mfc6_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_KERNEL);
747 return NULL;
748
749 dev_net_set(dev, net);
750
751 if (register_netdevice(dev)) {
752 free_netdev(dev);
753 return NULL;
754 }

--- 312 unchanged lines hidden (view full) ---

1067}
1068
1069/*
1070 * Allocate a multicast cache entry
1071 */
1072static struct mfc6_cache *ip6mr_cache_alloc(void)
1073{
1074 struct mfc6_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_KERNEL);
1077 if (c == NULL)
1075 if (!c)
1078 return NULL;
1079 c->mfc_un.res.minvif = MAXMIFS;
1080 return c;
1081}
1082
1083static struct mfc6_cache *ip6mr_cache_alloc_unres(void)
1084{
1085 struct mfc6_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_ATOMIC);
1076 return NULL;
1077 c->mfc_un.res.minvif = MAXMIFS;
1078 return c;
1079}
1080
1081static struct mfc6_cache *ip6mr_cache_alloc_unres(void)
1082{
1083 struct mfc6_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_ATOMIC);
1086 if (c == NULL)
1084 if (!c)
1087 return NULL;
1088 skb_queue_head_init(&c->mfc_un.unres.unresolved);
1089 c->mfc_un.unres.expires = jiffies + 10 * HZ;
1090 return c;
1091}
1092
1093/*
1094 * A cache entry has gone into a resolved state from queued

--- 100 unchanged lines hidden (view full) ---

1195 msg->im6_pad = 0;
1196 msg->im6_src = ipv6_hdr(pkt)->saddr;
1197 msg->im6_dst = ipv6_hdr(pkt)->daddr;
1198
1199 skb_dst_set(skb, dst_clone(skb_dst(pkt)));
1200 skb->ip_summed = CHECKSUM_UNNECESSARY;
1201 }
1202
1085 return NULL;
1086 skb_queue_head_init(&c->mfc_un.unres.unresolved);
1087 c->mfc_un.unres.expires = jiffies + 10 * HZ;
1088 return c;
1089}
1090
1091/*
1092 * A cache entry has gone into a resolved state from queued

--- 100 unchanged lines hidden (view full) ---

1193 msg->im6_pad = 0;
1194 msg->im6_src = ipv6_hdr(pkt)->saddr;
1195 msg->im6_dst = ipv6_hdr(pkt)->daddr;
1196
1197 skb_dst_set(skb, dst_clone(skb_dst(pkt)));
1198 skb->ip_summed = CHECKSUM_UNNECESSARY;
1199 }
1200
1203 if (mrt->mroute6_sk == NULL) {
1201 if (!mrt->mroute6_sk) {
1204 kfree_skb(skb);
1205 return -EINVAL;
1206 }
1207
1208 /*
1209 * Deliver to user space multicast routing algorithms
1210 */
1211 ret = sock_queue_rcv_skb(mrt->mroute6_sk, skb);

--- 278 unchanged lines hidden (view full) ---

1490 return 0;
1491 }
1492
1493 if (!ipv6_addr_any(&mfc->mf6cc_mcastgrp.sin6_addr) &&
1494 !ipv6_addr_is_multicast(&mfc->mf6cc_mcastgrp.sin6_addr))
1495 return -EINVAL;
1496
1497 c = ip6mr_cache_alloc();
1202 kfree_skb(skb);
1203 return -EINVAL;
1204 }
1205
1206 /*
1207 * Deliver to user space multicast routing algorithms
1208 */
1209 ret = sock_queue_rcv_skb(mrt->mroute6_sk, skb);

--- 278 unchanged lines hidden (view full) ---

1488 return 0;
1489 }
1490
1491 if (!ipv6_addr_any(&mfc->mf6cc_mcastgrp.sin6_addr) &&
1492 !ipv6_addr_is_multicast(&mfc->mf6cc_mcastgrp.sin6_addr))
1493 return -EINVAL;
1494
1495 c = ip6mr_cache_alloc();
1498 if (c == NULL)
1496 if (!c)
1499 return -ENOMEM;
1500
1501 c->mf6c_origin = mfc->mf6cc_origin.sin6_addr;
1502 c->mf6c_mcastgrp = mfc->mf6cc_mcastgrp.sin6_addr;
1503 c->mf6c_parent = mfc->mf6cc_parent;
1504 ip6mr_update_thresholds(mrt, c, ttls);
1505 if (!mrtsock)
1506 c->mfc_flags |= MFC_STATIC;

--- 153 unchanged lines hidden (view full) ---

1660 int ret, parent = 0;
1661 struct mif6ctl vif;
1662 struct mf6cctl mfc;
1663 mifi_t mifi;
1664 struct net *net = sock_net(sk);
1665 struct mr6_table *mrt;
1666
1667 mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT);
1497 return -ENOMEM;
1498
1499 c->mf6c_origin = mfc->mf6cc_origin.sin6_addr;
1500 c->mf6c_mcastgrp = mfc->mf6cc_mcastgrp.sin6_addr;
1501 c->mf6c_parent = mfc->mf6cc_parent;
1502 ip6mr_update_thresholds(mrt, c, ttls);
1503 if (!mrtsock)
1504 c->mfc_flags |= MFC_STATIC;

--- 153 unchanged lines hidden (view full) ---

1658 int ret, parent = 0;
1659 struct mif6ctl vif;
1660 struct mf6cctl mfc;
1661 mifi_t mifi;
1662 struct net *net = sock_net(sk);
1663 struct mr6_table *mrt;
1664
1665 mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT);
1668 if (mrt == NULL)
1666 if (!mrt)
1669 return -ENOENT;
1670
1671 if (optname != MRT6_INIT) {
1672 if (sk != mrt->mroute6_sk && !ns_capable(net->user_ns, CAP_NET_ADMIN))
1673 return -EACCES;
1674 }
1675
1676 switch (optname) {

--- 132 unchanged lines hidden (view full) ---

1809 int __user *optlen)
1810{
1811 int olr;
1812 int val;
1813 struct net *net = sock_net(sk);
1814 struct mr6_table *mrt;
1815
1816 mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT);
1667 return -ENOENT;
1668
1669 if (optname != MRT6_INIT) {
1670 if (sk != mrt->mroute6_sk && !ns_capable(net->user_ns, CAP_NET_ADMIN))
1671 return -EACCES;
1672 }
1673
1674 switch (optname) {

--- 132 unchanged lines hidden (view full) ---

1807 int __user *optlen)
1808{
1809 int olr;
1810 int val;
1811 struct net *net = sock_net(sk);
1812 struct mr6_table *mrt;
1813
1814 mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT);
1817 if (mrt == NULL)
1815 if (!mrt)
1818 return -ENOENT;
1819
1820 switch (optname) {
1821 case MRT6_VERSION:
1822 val = 0x0305;
1823 break;
1824#ifdef CONFIG_IPV6_PIMSM_V2
1825 case MRT6_PIM:

--- 30 unchanged lines hidden (view full) ---

1856 struct sioc_sg_req6 sr;
1857 struct sioc_mif_req6 vr;
1858 struct mif_device *vif;
1859 struct mfc6_cache *c;
1860 struct net *net = sock_net(sk);
1861 struct mr6_table *mrt;
1862
1863 mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT);
1816 return -ENOENT;
1817
1818 switch (optname) {
1819 case MRT6_VERSION:
1820 val = 0x0305;
1821 break;
1822#ifdef CONFIG_IPV6_PIMSM_V2
1823 case MRT6_PIM:

--- 30 unchanged lines hidden (view full) ---

1854 struct sioc_sg_req6 sr;
1855 struct sioc_mif_req6 vr;
1856 struct mif_device *vif;
1857 struct mfc6_cache *c;
1858 struct net *net = sock_net(sk);
1859 struct mr6_table *mrt;
1860
1861 mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT);
1864 if (mrt == NULL)
1862 if (!mrt)
1865 return -ENOENT;
1866
1867 switch (cmd) {
1868 case SIOCGETMIFCNT_IN6:
1869 if (copy_from_user(&vr, arg, sizeof(vr)))
1870 return -EFAULT;
1871 if (vr.mifi >= mrt->maxvif)
1872 return -EINVAL;

--- 57 unchanged lines hidden (view full) ---

1930 struct compat_sioc_sg_req6 sr;
1931 struct compat_sioc_mif_req6 vr;
1932 struct mif_device *vif;
1933 struct mfc6_cache *c;
1934 struct net *net = sock_net(sk);
1935 struct mr6_table *mrt;
1936
1937 mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT);
1863 return -ENOENT;
1864
1865 switch (cmd) {
1866 case SIOCGETMIFCNT_IN6:
1867 if (copy_from_user(&vr, arg, sizeof(vr)))
1868 return -EFAULT;
1869 if (vr.mifi >= mrt->maxvif)
1870 return -EINVAL;

--- 57 unchanged lines hidden (view full) ---

1928 struct compat_sioc_sg_req6 sr;
1929 struct compat_sioc_mif_req6 vr;
1930 struct mif_device *vif;
1931 struct mfc6_cache *c;
1932 struct net *net = sock_net(sk);
1933 struct mr6_table *mrt;
1934
1935 mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT);
1938 if (mrt == NULL)
1936 if (!mrt)
1939 return -ENOENT;
1940
1941 switch (cmd) {
1942 case SIOCGETMIFCNT_IN6:
1943 if (copy_from_user(&vr, arg, sizeof(vr)))
1944 return -EFAULT;
1945 if (vr.mifi >= mrt->maxvif)
1946 return -EINVAL;

--- 53 unchanged lines hidden (view full) ---

2000 struct sk_buff *skb, struct mfc6_cache *c, int vifi)
2001{
2002 struct ipv6hdr *ipv6h;
2003 struct mif_device *vif = &mrt->vif6_table[vifi];
2004 struct net_device *dev;
2005 struct dst_entry *dst;
2006 struct flowi6 fl6;
2007
1937 return -ENOENT;
1938
1939 switch (cmd) {
1940 case SIOCGETMIFCNT_IN6:
1941 if (copy_from_user(&vr, arg, sizeof(vr)))
1942 return -EFAULT;
1943 if (vr.mifi >= mrt->maxvif)
1944 return -EINVAL;

--- 53 unchanged lines hidden (view full) ---

1998 struct sk_buff *skb, struct mfc6_cache *c, int vifi)
1999{
2000 struct ipv6hdr *ipv6h;
2001 struct mif_device *vif = &mrt->vif6_table[vifi];
2002 struct net_device *dev;
2003 struct dst_entry *dst;
2004 struct flowi6 fl6;
2005
2008 if (vif->dev == NULL)
2006 if (!vif->dev)
2009 goto out_free;
2010
2011#ifdef CONFIG_IPV6_PIMSM_V2
2012 if (vif->flags & MIFF_REGISTER) {
2013 vif->pkt_out++;
2014 vif->bytes_out += skb->len;
2015 vif->dev->stats.tx_bytes += skb->len;
2016 vif->dev->stats.tx_packets++;

--- 172 unchanged lines hidden (view full) ---

2189 if (err < 0) {
2190 kfree_skb(skb);
2191 return err;
2192 }
2193
2194 read_lock(&mrt_lock);
2195 cache = ip6mr_cache_find(mrt,
2196 &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr);
2007 goto out_free;
2008
2009#ifdef CONFIG_IPV6_PIMSM_V2
2010 if (vif->flags & MIFF_REGISTER) {
2011 vif->pkt_out++;
2012 vif->bytes_out += skb->len;
2013 vif->dev->stats.tx_bytes += skb->len;
2014 vif->dev->stats.tx_packets++;

--- 172 unchanged lines hidden (view full) ---

2187 if (err < 0) {
2188 kfree_skb(skb);
2189 return err;
2190 }
2191
2192 read_lock(&mrt_lock);
2193 cache = ip6mr_cache_find(mrt,
2194 &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr);
2197 if (cache == NULL) {
2195 if (!cache) {
2198 int vif = ip6mr_find_vif(mrt, skb->dev);
2199
2200 if (vif >= 0)
2201 cache = ip6mr_cache_find_any(mrt,
2202 &ipv6_hdr(skb)->daddr,
2203 vif);
2204 }
2205
2206 /*
2207 * No usable cache entry
2208 */
2196 int vif = ip6mr_find_vif(mrt, skb->dev);
2197
2198 if (vif >= 0)
2199 cache = ip6mr_cache_find_any(mrt,
2200 &ipv6_hdr(skb)->daddr,
2201 vif);
2202 }
2203
2204 /*
2205 * No usable cache entry
2206 */
2209 if (cache == NULL) {
2207 if (!cache) {
2210 int vif;
2211
2212 vif = ip6mr_find_vif(mrt, skb->dev);
2213 if (vif >= 0) {
2214 int err = ip6mr_cache_unresolved(mrt, vif, skb);
2215 read_unlock(&mrt_lock);
2216
2217 return err;

--- 22 unchanged lines hidden (view full) ---

2240 /* If cache is unresolved, don't try to parse IIF and OIF */
2241 if (c->mf6c_parent >= MAXMIFS)
2242 return -ENOENT;
2243
2244 if (MIF_EXISTS(mrt, c->mf6c_parent) &&
2245 nla_put_u32(skb, RTA_IIF, mrt->vif6_table[c->mf6c_parent].dev->ifindex) < 0)
2246 return -EMSGSIZE;
2247 mp_attr = nla_nest_start(skb, RTA_MULTIPATH);
2208 int vif;
2209
2210 vif = ip6mr_find_vif(mrt, skb->dev);
2211 if (vif >= 0) {
2212 int err = ip6mr_cache_unresolved(mrt, vif, skb);
2213 read_unlock(&mrt_lock);
2214
2215 return err;

--- 22 unchanged lines hidden (view full) ---

2238 /* If cache is unresolved, don't try to parse IIF and OIF */
2239 if (c->mf6c_parent >= MAXMIFS)
2240 return -ENOENT;
2241
2242 if (MIF_EXISTS(mrt, c->mf6c_parent) &&
2243 nla_put_u32(skb, RTA_IIF, mrt->vif6_table[c->mf6c_parent].dev->ifindex) < 0)
2244 return -EMSGSIZE;
2245 mp_attr = nla_nest_start(skb, RTA_MULTIPATH);
2248 if (mp_attr == NULL)
2246 if (!mp_attr)
2249 return -EMSGSIZE;
2250
2251 for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) {
2252 if (MIF_EXISTS(mrt, ct) && c->mfc_un.res.ttls[ct] < 255) {
2253 nhp = nla_reserve_nohdr(skb, sizeof(*nhp));
2247 return -EMSGSIZE;
2248
2249 for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) {
2250 if (MIF_EXISTS(mrt, ct) && c->mfc_un.res.ttls[ct] < 255) {
2251 nhp = nla_reserve_nohdr(skb, sizeof(*nhp));
2254 if (nhp == NULL) {
2252 if (!nhp) {
2255 nla_nest_cancel(skb, mp_attr);
2256 return -EMSGSIZE;
2257 }
2258
2259 nhp->rtnh_flags = 0;
2260 nhp->rtnh_hops = c->mfc_un.res.ttls[ct];
2261 nhp->rtnh_ifindex = mrt->vif6_table[ct].dev->ifindex;
2262 nhp->rtnh_len = sizeof(*nhp);

--- 16 unchanged lines hidden (view full) ---

2279 struct sk_buff *skb, struct rtmsg *rtm, int nowait)
2280{
2281 int err;
2282 struct mr6_table *mrt;
2283 struct mfc6_cache *cache;
2284 struct rt6_info *rt = (struct rt6_info *)skb_dst(skb);
2285
2286 mrt = ip6mr_get_table(net, RT6_TABLE_DFLT);
2253 nla_nest_cancel(skb, mp_attr);
2254 return -EMSGSIZE;
2255 }
2256
2257 nhp->rtnh_flags = 0;
2258 nhp->rtnh_hops = c->mfc_un.res.ttls[ct];
2259 nhp->rtnh_ifindex = mrt->vif6_table[ct].dev->ifindex;
2260 nhp->rtnh_len = sizeof(*nhp);

--- 16 unchanged lines hidden (view full) ---

2277 struct sk_buff *skb, struct rtmsg *rtm, int nowait)
2278{
2279 int err;
2280 struct mr6_table *mrt;
2281 struct mfc6_cache *cache;
2282 struct rt6_info *rt = (struct rt6_info *)skb_dst(skb);
2283
2284 mrt = ip6mr_get_table(net, RT6_TABLE_DFLT);
2287 if (mrt == NULL)
2285 if (!mrt)
2288 return -ENOENT;
2289
2290 read_lock(&mrt_lock);
2291 cache = ip6mr_cache_find(mrt, &rt->rt6i_src.addr, &rt->rt6i_dst.addr);
2292 if (!cache && skb->dev) {
2293 int vif = ip6mr_find_vif(mrt, skb->dev);
2294
2295 if (vif >= 0)

--- 8 unchanged lines hidden (view full) ---

2304 int vif;
2305
2306 if (nowait) {
2307 read_unlock(&mrt_lock);
2308 return -EAGAIN;
2309 }
2310
2311 dev = skb->dev;
2286 return -ENOENT;
2287
2288 read_lock(&mrt_lock);
2289 cache = ip6mr_cache_find(mrt, &rt->rt6i_src.addr, &rt->rt6i_dst.addr);
2290 if (!cache && skb->dev) {
2291 int vif = ip6mr_find_vif(mrt, skb->dev);
2292
2293 if (vif >= 0)

--- 8 unchanged lines hidden (view full) ---

2302 int vif;
2303
2304 if (nowait) {
2305 read_unlock(&mrt_lock);
2306 return -EAGAIN;
2307 }
2308
2309 dev = skb->dev;
2312 if (dev == NULL || (vif = ip6mr_find_vif(mrt, dev)) < 0) {
2310 if (!dev || (vif = ip6mr_find_vif(mrt, dev)) < 0) {
2313 read_unlock(&mrt_lock);
2314 return -ENODEV;
2315 }
2316
2317 /* really correct? */
2318 skb2 = alloc_skb(sizeof(struct ipv6hdr), GFP_ATOMIC);
2319 if (!skb2) {
2320 read_unlock(&mrt_lock);

--- 35 unchanged lines hidden (view full) ---

2356 u32 portid, u32 seq, struct mfc6_cache *c, int cmd,
2357 int flags)
2358{
2359 struct nlmsghdr *nlh;
2360 struct rtmsg *rtm;
2361 int err;
2362
2363 nlh = nlmsg_put(skb, portid, seq, cmd, sizeof(*rtm), flags);
2311 read_unlock(&mrt_lock);
2312 return -ENODEV;
2313 }
2314
2315 /* really correct? */
2316 skb2 = alloc_skb(sizeof(struct ipv6hdr), GFP_ATOMIC);
2317 if (!skb2) {
2318 read_unlock(&mrt_lock);

--- 35 unchanged lines hidden (view full) ---

2354 u32 portid, u32 seq, struct mfc6_cache *c, int cmd,
2355 int flags)
2356{
2357 struct nlmsghdr *nlh;
2358 struct rtmsg *rtm;
2359 int err;
2360
2361 nlh = nlmsg_put(skb, portid, seq, cmd, sizeof(*rtm), flags);
2364 if (nlh == NULL)
2362 if (!nlh)
2365 return -EMSGSIZE;
2366
2367 rtm = nlmsg_data(nlh);
2368 rtm->rtm_family = RTNL_FAMILY_IP6MR;
2369 rtm->rtm_dst_len = 128;
2370 rtm->rtm_src_len = 128;
2371 rtm->rtm_tos = 0;
2372 rtm->rtm_table = mrt->id;

--- 48 unchanged lines hidden (view full) ---

2421 int cmd)
2422{
2423 struct net *net = read_pnet(&mrt->net);
2424 struct sk_buff *skb;
2425 int err = -ENOBUFS;
2426
2427 skb = nlmsg_new(mr6_msgsize(mfc->mf6c_parent >= MAXMIFS, mrt->maxvif),
2428 GFP_ATOMIC);
2363 return -EMSGSIZE;
2364
2365 rtm = nlmsg_data(nlh);
2366 rtm->rtm_family = RTNL_FAMILY_IP6MR;
2367 rtm->rtm_dst_len = 128;
2368 rtm->rtm_src_len = 128;
2369 rtm->rtm_tos = 0;
2370 rtm->rtm_table = mrt->id;

--- 48 unchanged lines hidden (view full) ---

2419 int cmd)
2420{
2421 struct net *net = read_pnet(&mrt->net);
2422 struct sk_buff *skb;
2423 int err = -ENOBUFS;
2424
2425 skb = nlmsg_new(mr6_msgsize(mfc->mf6c_parent >= MAXMIFS, mrt->maxvif),
2426 GFP_ATOMIC);
2429 if (skb == NULL)
2427 if (!skb)
2430 goto errout;
2431
2432 err = ip6mr_fill_mroute(mrt, skb, 0, 0, mfc, cmd, 0);
2433 if (err < 0)
2434 goto errout;
2435
2436 rtnl_notify(skb, net, 0, RTNLGRP_IPV6_MROUTE, NULL, GFP_ATOMIC);
2437 return;

--- 71 unchanged lines hidden ---
2428 goto errout;
2429
2430 err = ip6mr_fill_mroute(mrt, skb, 0, 0, mfc, cmd, 0);
2431 if (err < 0)
2432 goto errout;
2433
2434 rtnl_notify(skb, net, 0, RTNLGRP_IPV6_MROUTE, NULL, GFP_ATOMIC);
2435 return;

--- 71 unchanged lines hidden ---