diff options
Diffstat (limited to 'net/ipv4/ipmr.c')
-rw-r--r-- | net/ipv4/ipmr.c | 48 |
1 files changed, 26 insertions, 22 deletions
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 13e9dd3012b3..9a8da5ed92b7 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -226,9 +226,10 @@ static void reg_vif_setup(struct net_device *dev) | |||
226 | dev->flags = IFF_NOARP; | 226 | dev->flags = IFF_NOARP; |
227 | dev->netdev_ops = ®_vif_netdev_ops, | 227 | dev->netdev_ops = ®_vif_netdev_ops, |
228 | dev->destructor = free_netdev; | 228 | dev->destructor = free_netdev; |
229 | dev->features |= NETIF_F_NETNS_LOCAL; | ||
229 | } | 230 | } |
230 | 231 | ||
231 | static struct net_device *ipmr_reg_vif(void) | 232 | static struct net_device *ipmr_reg_vif(struct net *net) |
232 | { | 233 | { |
233 | struct net_device *dev; | 234 | struct net_device *dev; |
234 | struct in_device *in_dev; | 235 | struct in_device *in_dev; |
@@ -238,6 +239,8 @@ static struct net_device *ipmr_reg_vif(void) | |||
238 | if (dev == NULL) | 239 | if (dev == NULL) |
239 | return NULL; | 240 | return NULL; |
240 | 241 | ||
242 | dev_net_set(dev, net); | ||
243 | |||
241 | if (register_netdevice(dev)) { | 244 | if (register_netdevice(dev)) { |
242 | free_netdev(dev); | 245 | free_netdev(dev); |
243 | return NULL; | 246 | return NULL; |
@@ -448,7 +451,7 @@ static int vif_add(struct net *net, struct vifctl *vifc, int mrtsock) | |||
448 | */ | 451 | */ |
449 | if (net->ipv4.mroute_reg_vif_num >= 0) | 452 | if (net->ipv4.mroute_reg_vif_num >= 0) |
450 | return -EADDRINUSE; | 453 | return -EADDRINUSE; |
451 | dev = ipmr_reg_vif(); | 454 | dev = ipmr_reg_vif(net); |
452 | if (!dev) | 455 | if (!dev) |
453 | return -ENOBUFS; | 456 | return -ENOBUFS; |
454 | err = dev_set_allmulti(dev, 1); | 457 | err = dev_set_allmulti(dev, 1); |
@@ -651,7 +654,7 @@ static int ipmr_cache_report(struct net *net, | |||
651 | ip_hdr(skb)->protocol = 0; /* Flag to the kernel this is a route add */ | 654 | ip_hdr(skb)->protocol = 0; /* Flag to the kernel this is a route add */ |
652 | msg = (struct igmpmsg *)skb_network_header(skb); | 655 | msg = (struct igmpmsg *)skb_network_header(skb); |
653 | msg->im_vif = vifi; | 656 | msg->im_vif = vifi; |
654 | skb->dst = dst_clone(pkt->dst); | 657 | skb_dst_set(skb, dst_clone(skb_dst(pkt))); |
655 | 658 | ||
656 | /* | 659 | /* |
657 | * Add our header | 660 | * Add our header |
@@ -1031,16 +1034,6 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int | |||
1031 | if (v != net->ipv4.mroute_do_pim) { | 1034 | if (v != net->ipv4.mroute_do_pim) { |
1032 | net->ipv4.mroute_do_pim = v; | 1035 | net->ipv4.mroute_do_pim = v; |
1033 | net->ipv4.mroute_do_assert = v; | 1036 | net->ipv4.mroute_do_assert = v; |
1034 | #ifdef CONFIG_IP_PIMSM_V2 | ||
1035 | if (net->ipv4.mroute_do_pim) | ||
1036 | ret = inet_add_protocol(&pim_protocol, | ||
1037 | IPPROTO_PIM); | ||
1038 | else | ||
1039 | ret = inet_del_protocol(&pim_protocol, | ||
1040 | IPPROTO_PIM); | ||
1041 | if (ret < 0) | ||
1042 | ret = -EAGAIN; | ||
1043 | #endif | ||
1044 | } | 1037 | } |
1045 | rtnl_unlock(); | 1038 | rtnl_unlock(); |
1046 | return ret; | 1039 | return ret; |
@@ -1201,7 +1194,7 @@ static void ip_encap(struct sk_buff *skb, __be32 saddr, __be32 daddr) | |||
1201 | iph->protocol = IPPROTO_IPIP; | 1194 | iph->protocol = IPPROTO_IPIP; |
1202 | iph->ihl = 5; | 1195 | iph->ihl = 5; |
1203 | iph->tot_len = htons(skb->len); | 1196 | iph->tot_len = htons(skb->len); |
1204 | ip_select_ident(iph, skb->dst, NULL); | 1197 | ip_select_ident(iph, skb_dst(skb), NULL); |
1205 | ip_send_check(iph); | 1198 | ip_send_check(iph); |
1206 | 1199 | ||
1207 | memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); | 1200 | memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); |
@@ -1212,7 +1205,7 @@ static inline int ipmr_forward_finish(struct sk_buff *skb) | |||
1212 | { | 1205 | { |
1213 | struct ip_options * opt = &(IPCB(skb)->opt); | 1206 | struct ip_options * opt = &(IPCB(skb)->opt); |
1214 | 1207 | ||
1215 | IP_INC_STATS_BH(dev_net(skb->dst->dev), IPSTATS_MIB_OUTFORWDATAGRAMS); | 1208 | IP_INC_STATS_BH(dev_net(skb_dst(skb)->dev), IPSTATS_MIB_OUTFORWDATAGRAMS); |
1216 | 1209 | ||
1217 | if (unlikely(opt->optlen)) | 1210 | if (unlikely(opt->optlen)) |
1218 | ip_forward_options(skb); | 1211 | ip_forward_options(skb); |
@@ -1290,8 +1283,8 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, int vifi) | |||
1290 | vif->pkt_out++; | 1283 | vif->pkt_out++; |
1291 | vif->bytes_out += skb->len; | 1284 | vif->bytes_out += skb->len; |
1292 | 1285 | ||
1293 | dst_release(skb->dst); | 1286 | skb_dst_drop(skb); |
1294 | skb->dst = &rt->u.dst; | 1287 | skb_dst_set(skb, &rt->u.dst); |
1295 | ip_decrease_ttl(ip_hdr(skb)); | 1288 | ip_decrease_ttl(ip_hdr(skb)); |
1296 | 1289 | ||
1297 | /* FIXME: forward and output firewalls used to be called here. | 1290 | /* FIXME: forward and output firewalls used to be called here. |
@@ -1354,7 +1347,7 @@ static int ip_mr_forward(struct sk_buff *skb, struct mfc_cache *cache, int local | |||
1354 | if (net->ipv4.vif_table[vif].dev != skb->dev) { | 1347 | if (net->ipv4.vif_table[vif].dev != skb->dev) { |
1355 | int true_vifi; | 1348 | int true_vifi; |
1356 | 1349 | ||
1357 | if (skb->rtable->fl.iif == 0) { | 1350 | if (skb_rtable(skb)->fl.iif == 0) { |
1358 | /* It is our own packet, looped back. | 1351 | /* It is our own packet, looped back. |
1359 | Very complicated situation... | 1352 | Very complicated situation... |
1360 | 1353 | ||
@@ -1430,7 +1423,7 @@ int ip_mr_input(struct sk_buff *skb) | |||
1430 | { | 1423 | { |
1431 | struct mfc_cache *cache; | 1424 | struct mfc_cache *cache; |
1432 | struct net *net = dev_net(skb->dev); | 1425 | struct net *net = dev_net(skb->dev); |
1433 | int local = skb->rtable->rt_flags&RTCF_LOCAL; | 1426 | int local = skb_rtable(skb)->rt_flags & RTCF_LOCAL; |
1434 | 1427 | ||
1435 | /* Packet is looped back after forward, it should not be | 1428 | /* Packet is looped back after forward, it should not be |
1436 | forwarded second time, but still can be delivered locally. | 1429 | forwarded second time, but still can be delivered locally. |
@@ -1543,8 +1536,7 @@ static int __pim_rcv(struct sk_buff *skb, unsigned int pimlen) | |||
1543 | skb->protocol = htons(ETH_P_IP); | 1536 | skb->protocol = htons(ETH_P_IP); |
1544 | skb->ip_summed = 0; | 1537 | skb->ip_summed = 0; |
1545 | skb->pkt_type = PACKET_HOST; | 1538 | skb->pkt_type = PACKET_HOST; |
1546 | dst_release(skb->dst); | 1539 | skb_dst_drop(skb); |
1547 | skb->dst = NULL; | ||
1548 | reg_dev->stats.rx_bytes += skb->len; | 1540 | reg_dev->stats.rx_bytes += skb->len; |
1549 | reg_dev->stats.rx_packets++; | 1541 | reg_dev->stats.rx_packets++; |
1550 | nf_reset(skb); | 1542 | nf_reset(skb); |
@@ -1646,7 +1638,7 @@ int ipmr_get_route(struct net *net, | |||
1646 | { | 1638 | { |
1647 | int err; | 1639 | int err; |
1648 | struct mfc_cache *cache; | 1640 | struct mfc_cache *cache; |
1649 | struct rtable *rt = skb->rtable; | 1641 | struct rtable *rt = skb_rtable(skb); |
1650 | 1642 | ||
1651 | read_lock(&mrt_lock); | 1643 | read_lock(&mrt_lock); |
1652 | cache = ipmr_cache_find(net, rt->rt_src, rt->rt_dst); | 1644 | cache = ipmr_cache_find(net, rt->rt_src, rt->rt_dst); |
@@ -1955,6 +1947,7 @@ static const struct file_operations ipmr_mfc_fops = { | |||
1955 | #ifdef CONFIG_IP_PIMSM_V2 | 1947 | #ifdef CONFIG_IP_PIMSM_V2 |
1956 | static struct net_protocol pim_protocol = { | 1948 | static struct net_protocol pim_protocol = { |
1957 | .handler = pim_rcv, | 1949 | .handler = pim_rcv, |
1950 | .netns_ok = 1, | ||
1958 | }; | 1951 | }; |
1959 | #endif | 1952 | #endif |
1960 | 1953 | ||
@@ -2041,8 +2034,19 @@ int __init ip_mr_init(void) | |||
2041 | err = register_netdevice_notifier(&ip_mr_notifier); | 2034 | err = register_netdevice_notifier(&ip_mr_notifier); |
2042 | if (err) | 2035 | if (err) |
2043 | goto reg_notif_fail; | 2036 | goto reg_notif_fail; |
2037 | #ifdef CONFIG_IP_PIMSM_V2 | ||
2038 | if (inet_add_protocol(&pim_protocol, IPPROTO_PIM) < 0) { | ||
2039 | printk(KERN_ERR "ip_mr_init: can't add PIM protocol\n"); | ||
2040 | err = -EAGAIN; | ||
2041 | goto add_proto_fail; | ||
2042 | } | ||
2043 | #endif | ||
2044 | return 0; | 2044 | return 0; |
2045 | 2045 | ||
2046 | #ifdef CONFIG_IP_PIMSM_V2 | ||
2047 | add_proto_fail: | ||
2048 | unregister_netdevice_notifier(&ip_mr_notifier); | ||
2049 | #endif | ||
2046 | reg_notif_fail: | 2050 | reg_notif_fail: |
2047 | del_timer(&ipmr_expire_timer); | 2051 | del_timer(&ipmr_expire_timer); |
2048 | unregister_pernet_subsys(&ipmr_net_ops); | 2052 | unregister_pernet_subsys(&ipmr_net_ops); |