mcast.c (54ff9ef36bdf84d469a098cbf8e2a103fbc77054) mcast.c (63159f29be1df7f93563a8a0f78c5e65fc844ed6)
1/*
2 * Multicast support for IPv6
3 * Linux INET6 implementation
4 *
5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt>
7 *
8 * Based on linux/ipv4/igmp.c and linux/ipv4/ip_sockglue.c

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

152 rcu_read_unlock();
153 return -EADDRINUSE;
154 }
155 }
156 rcu_read_unlock();
157
158 mc_lst = sock_kmalloc(sk, sizeof(struct ipv6_mc_socklist), GFP_KERNEL);
159
1/*
2 * Multicast support for IPv6
3 * Linux INET6 implementation
4 *
5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt>
7 *
8 * Based on linux/ipv4/igmp.c and linux/ipv4/ip_sockglue.c

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

152 rcu_read_unlock();
153 return -EADDRINUSE;
154 }
155 }
156 rcu_read_unlock();
157
158 mc_lst = sock_kmalloc(sk, sizeof(struct ipv6_mc_socklist), GFP_KERNEL);
159
160 if (mc_lst == NULL)
160 if (!mc_lst)
161 return -ENOMEM;
162
163 mc_lst->next = NULL;
164 mc_lst->addr = *addr;
165
166 if (ifindex == 0) {
167 struct rt6_info *rt;
168 rt = rt6_lookup(net, addr, NULL, 0, 0);
169 if (rt) {
170 dev = rt->dst.dev;
171 ip6_rt_put(rt);
172 }
173 } else
174 dev = __dev_get_by_index(net, ifindex);
175
161 return -ENOMEM;
162
163 mc_lst->next = NULL;
164 mc_lst->addr = *addr;
165
166 if (ifindex == 0) {
167 struct rt6_info *rt;
168 rt = rt6_lookup(net, addr, NULL, 0, 0);
169 if (rt) {
170 dev = rt->dst.dev;
171 ip6_rt_put(rt);
172 }
173 } else
174 dev = __dev_get_by_index(net, ifindex);
175
176 if (dev == NULL) {
176 if (!dev) {
177 sock_kfree_s(sk, mc_lst, sizeof(*mc_lst));
178 return -ENODEV;
179 }
180
181 mc_lst->ifindex = dev->ifindex;
182 mc_lst->sfmode = MCAST_EXCLUDE;
183 rwlock_init(&mc_lst->sflock);
184 mc_lst->sflist = NULL;

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

818}
819
820static struct ifmcaddr6 *mca_alloc(struct inet6_dev *idev,
821 const struct in6_addr *addr)
822{
823 struct ifmcaddr6 *mc;
824
825 mc = kzalloc(sizeof(*mc), GFP_ATOMIC);
177 sock_kfree_s(sk, mc_lst, sizeof(*mc_lst));
178 return -ENODEV;
179 }
180
181 mc_lst->ifindex = dev->ifindex;
182 mc_lst->sfmode = MCAST_EXCLUDE;
183 rwlock_init(&mc_lst->sflock);
184 mc_lst->sflist = NULL;

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

818}
819
820static struct ifmcaddr6 *mca_alloc(struct inet6_dev *idev,
821 const struct in6_addr *addr)
822{
823 struct ifmcaddr6 *mc;
824
825 mc = kzalloc(sizeof(*mc), GFP_ATOMIC);
826 if (mc == NULL)
826 if (!mc)
827 return NULL;
828
829 setup_timer(&mc->mca_timer, igmp6_timer_handler, (unsigned long)mc);
830
831 mc->mca_addr = *addr;
832 mc->idev = idev; /* reference taken by caller */
833 mc->mca_users = 1;
834 /* mca_stamp should be updated upon changes */

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

855 struct ifmcaddr6 *mc;
856 struct inet6_dev *idev;
857
858 ASSERT_RTNL();
859
860 /* we need to take a reference on idev */
861 idev = in6_dev_get(dev);
862
827 return NULL;
828
829 setup_timer(&mc->mca_timer, igmp6_timer_handler, (unsigned long)mc);
830
831 mc->mca_addr = *addr;
832 mc->idev = idev; /* reference taken by caller */
833 mc->mca_users = 1;
834 /* mca_stamp should be updated upon changes */

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

855 struct ifmcaddr6 *mc;
856 struct inet6_dev *idev;
857
858 ASSERT_RTNL();
859
860 /* we need to take a reference on idev */
861 idev = in6_dev_get(dev);
862
863 if (idev == NULL)
863 if (!idev)
864 return -EINVAL;
865
866 write_lock_bh(&idev->lock);
867 if (idev->dead) {
868 write_unlock_bh(&idev->lock);
869 in6_dev_put(idev);
870 return -ENODEV;
871 }

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

1323 */
1324 if (!(ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL) ||
1325 ipv6_hdr(skb)->hop_limit != 1 ||
1326 !(IP6CB(skb)->flags & IP6SKB_ROUTERALERT) ||
1327 IP6CB(skb)->ra != htons(IPV6_OPT_ROUTERALERT_MLD))
1328 return -EINVAL;
1329
1330 idev = __in6_dev_get(skb->dev);
864 return -EINVAL;
865
866 write_lock_bh(&idev->lock);
867 if (idev->dead) {
868 write_unlock_bh(&idev->lock);
869 in6_dev_put(idev);
870 return -ENODEV;
871 }

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

1323 */
1324 if (!(ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL) ||
1325 ipv6_hdr(skb)->hop_limit != 1 ||
1326 !(IP6CB(skb)->flags & IP6SKB_ROUTERALERT) ||
1327 IP6CB(skb)->ra != htons(IPV6_OPT_ROUTERALERT_MLD))
1328 return -EINVAL;
1329
1330 idev = __in6_dev_get(skb->dev);
1331 if (idev == NULL)
1331 if (!idev)
1332 return 0;
1333
1334 mld = (struct mld_msg *)icmp6_hdr(skb);
1335 group = &mld->mld_mca;
1336 group_type = ipv6_addr_type(group);
1337
1338 if (group_type != IPV6_ADDR_ANY &&
1339 !(group_type&IPV6_ADDR_MULTICAST))

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

1438
1439 /* Drop reports with not link local source */
1440 addr_type = ipv6_addr_type(&ipv6_hdr(skb)->saddr);
1441 if (addr_type != IPV6_ADDR_ANY &&
1442 !(addr_type&IPV6_ADDR_LINKLOCAL))
1443 return -EINVAL;
1444
1445 idev = __in6_dev_get(skb->dev);
1332 return 0;
1333
1334 mld = (struct mld_msg *)icmp6_hdr(skb);
1335 group = &mld->mld_mca;
1336 group_type = ipv6_addr_type(group);
1337
1338 if (group_type != IPV6_ADDR_ANY &&
1339 !(group_type&IPV6_ADDR_MULTICAST))

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

1438
1439 /* Drop reports with not link local source */
1440 addr_type = ipv6_addr_type(&ipv6_hdr(skb)->saddr);
1441 if (addr_type != IPV6_ADDR_ANY &&
1442 !(addr_type&IPV6_ADDR_LINKLOCAL))
1443 return -EINVAL;
1444
1445 idev = __in6_dev_get(skb->dev);
1446 if (idev == NULL)
1446 if (!idev)
1447 return -ENODEV;
1448
1449 /*
1450 * Cancel the timer for this group
1451 */
1452
1453 read_lock_bh(&idev->lock);
1454 for (ma = idev->mc_list; ma; ma = ma->next) {

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

1957
1958 rcu_read_lock();
1959 IP6_UPD_PO_STATS(net, __in6_dev_get(dev),
1960 IPSTATS_MIB_OUT, full_len);
1961 rcu_read_unlock();
1962
1963 skb = sock_alloc_send_skb(sk, hlen + tlen + full_len, 1, &err);
1964
1447 return -ENODEV;
1448
1449 /*
1450 * Cancel the timer for this group
1451 */
1452
1453 read_lock_bh(&idev->lock);
1454 for (ma = idev->mc_list; ma; ma = ma->next) {

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

1957
1958 rcu_read_lock();
1959 IP6_UPD_PO_STATS(net, __in6_dev_get(dev),
1960 IPSTATS_MIB_OUT, full_len);
1961 rcu_read_unlock();
1962
1963 skb = sock_alloc_send_skb(sk, hlen + tlen + full_len, 1, &err);
1964
1965 if (skb == NULL) {
1965 if (!skb) {
1966 rcu_read_lock();
1967 IP6_INC_STATS(net, __in6_dev_get(dev),
1968 IPSTATS_MIB_OUTDISCARDS);
1969 rcu_read_unlock();
1970 return;
1971 }
1972 skb->priority = TC_PRIO_CONTROL;
1973 skb_reserve(skb, hlen);

--- 977 unchanged lines hidden ---
1966 rcu_read_lock();
1967 IP6_INC_STATS(net, __in6_dev_get(dev),
1968 IPSTATS_MIB_OUTDISCARDS);
1969 rcu_read_unlock();
1970 return;
1971 }
1972 skb->priority = TC_PRIO_CONTROL;
1973 skb_reserve(skb, hlen);

--- 977 unchanged lines hidden ---