diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/addrconf.c | 14 | ||||
-rw-r--r-- | net/ipv6/ah6.c | 2 | ||||
-rw-r--r-- | net/ipv6/anycast.c | 4 | ||||
-rw-r--r-- | net/ipv6/esp6.c | 2 | ||||
-rw-r--r-- | net/ipv6/ip6_fib.c | 19 | ||||
-rw-r--r-- | net/ipv6/ip6_output.c | 3 | ||||
-rw-r--r-- | net/ipv6/ipcomp6.c | 9 | ||||
-rw-r--r-- | net/ipv6/ipv6_sockglue.c | 5 | ||||
-rw-r--r-- | net/ipv6/mcast.c | 68 | ||||
-rw-r--r-- | net/ipv6/ndisc.c | 4 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6_tables.c | 1 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6t_LOG.c | 54 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6table_raw.c | 6 | ||||
-rw-r--r-- | net/ipv6/route.c | 78 | ||||
-rw-r--r-- | net/ipv6/xfrm6_tunnel.c | 2 |
15 files changed, 140 insertions, 131 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 47a30c3188ea..14f5c53235fe 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -695,7 +695,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) | |||
695 | 695 | ||
696 | if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) { | 696 | if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) { |
697 | if (onlink == 0) { | 697 | if (onlink == 0) { |
698 | ip6_del_rt(rt, NULL, NULL); | 698 | ip6_del_rt(rt, NULL, NULL, NULL); |
699 | rt = NULL; | 699 | rt = NULL; |
700 | } else if (!(rt->rt6i_flags & RTF_EXPIRES)) { | 700 | } else if (!(rt->rt6i_flags & RTF_EXPIRES)) { |
701 | rt->rt6i_expires = expires; | 701 | rt->rt6i_expires = expires; |
@@ -1340,7 +1340,7 @@ addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev, | |||
1340 | if (dev->type == ARPHRD_SIT && (dev->flags&IFF_POINTOPOINT)) | 1340 | if (dev->type == ARPHRD_SIT && (dev->flags&IFF_POINTOPOINT)) |
1341 | rtmsg.rtmsg_flags |= RTF_NONEXTHOP; | 1341 | rtmsg.rtmsg_flags |= RTF_NONEXTHOP; |
1342 | 1342 | ||
1343 | ip6_route_add(&rtmsg, NULL, NULL); | 1343 | ip6_route_add(&rtmsg, NULL, NULL, NULL); |
1344 | } | 1344 | } |
1345 | 1345 | ||
1346 | /* Create "default" multicast route to the interface */ | 1346 | /* Create "default" multicast route to the interface */ |
@@ -1357,7 +1357,7 @@ static void addrconf_add_mroute(struct net_device *dev) | |||
1357 | rtmsg.rtmsg_ifindex = dev->ifindex; | 1357 | rtmsg.rtmsg_ifindex = dev->ifindex; |
1358 | rtmsg.rtmsg_flags = RTF_UP; | 1358 | rtmsg.rtmsg_flags = RTF_UP; |
1359 | rtmsg.rtmsg_type = RTMSG_NEWROUTE; | 1359 | rtmsg.rtmsg_type = RTMSG_NEWROUTE; |
1360 | ip6_route_add(&rtmsg, NULL, NULL); | 1360 | ip6_route_add(&rtmsg, NULL, NULL, NULL); |
1361 | } | 1361 | } |
1362 | 1362 | ||
1363 | static void sit_route_add(struct net_device *dev) | 1363 | static void sit_route_add(struct net_device *dev) |
@@ -1374,7 +1374,7 @@ static void sit_route_add(struct net_device *dev) | |||
1374 | rtmsg.rtmsg_flags = RTF_UP|RTF_NONEXTHOP; | 1374 | rtmsg.rtmsg_flags = RTF_UP|RTF_NONEXTHOP; |
1375 | rtmsg.rtmsg_ifindex = dev->ifindex; | 1375 | rtmsg.rtmsg_ifindex = dev->ifindex; |
1376 | 1376 | ||
1377 | ip6_route_add(&rtmsg, NULL, NULL); | 1377 | ip6_route_add(&rtmsg, NULL, NULL, NULL); |
1378 | } | 1378 | } |
1379 | 1379 | ||
1380 | static void addrconf_add_lroute(struct net_device *dev) | 1380 | static void addrconf_add_lroute(struct net_device *dev) |
@@ -1467,7 +1467,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) | |||
1467 | if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) { | 1467 | if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) { |
1468 | if (rt->rt6i_flags&RTF_EXPIRES) { | 1468 | if (rt->rt6i_flags&RTF_EXPIRES) { |
1469 | if (valid_lft == 0) { | 1469 | if (valid_lft == 0) { |
1470 | ip6_del_rt(rt, NULL, NULL); | 1470 | ip6_del_rt(rt, NULL, NULL, NULL); |
1471 | rt = NULL; | 1471 | rt = NULL; |
1472 | } else { | 1472 | } else { |
1473 | rt->rt6i_expires = rt_expires; | 1473 | rt->rt6i_expires = rt_expires; |
@@ -3094,7 +3094,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) | |||
3094 | switch (event) { | 3094 | switch (event) { |
3095 | case RTM_NEWADDR: | 3095 | case RTM_NEWADDR: |
3096 | dst_hold(&ifp->rt->u.dst); | 3096 | dst_hold(&ifp->rt->u.dst); |
3097 | if (ip6_ins_rt(ifp->rt, NULL, NULL)) | 3097 | if (ip6_ins_rt(ifp->rt, NULL, NULL, NULL)) |
3098 | dst_release(&ifp->rt->u.dst); | 3098 | dst_release(&ifp->rt->u.dst); |
3099 | if (ifp->idev->cnf.forwarding) | 3099 | if (ifp->idev->cnf.forwarding) |
3100 | addrconf_join_anycast(ifp); | 3100 | addrconf_join_anycast(ifp); |
@@ -3104,7 +3104,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) | |||
3104 | addrconf_leave_anycast(ifp); | 3104 | addrconf_leave_anycast(ifp); |
3105 | addrconf_leave_solict(ifp->idev, &ifp->addr); | 3105 | addrconf_leave_solict(ifp->idev, &ifp->addr); |
3106 | dst_hold(&ifp->rt->u.dst); | 3106 | dst_hold(&ifp->rt->u.dst); |
3107 | if (ip6_del_rt(ifp->rt, NULL, NULL)) | 3107 | if (ip6_del_rt(ifp->rt, NULL, NULL, NULL)) |
3108 | dst_free(&ifp->rt->u.dst); | 3108 | dst_free(&ifp->rt->u.dst); |
3109 | else | 3109 | else |
3110 | dst_release(&ifp->rt->u.dst); | 3110 | dst_release(&ifp->rt->u.dst); |
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c index e3ecf626cbf7..986fdfdccbcd 100644 --- a/net/ipv6/ah6.c +++ b/net/ipv6/ah6.c | |||
@@ -339,7 +339,7 @@ static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
339 | xfrm_state_put(x); | 339 | xfrm_state_put(x); |
340 | } | 340 | } |
341 | 341 | ||
342 | static int ah6_init_state(struct xfrm_state *x, void *args) | 342 | static int ah6_init_state(struct xfrm_state *x) |
343 | { | 343 | { |
344 | struct ah_data *ahp = NULL; | 344 | struct ah_data *ahp = NULL; |
345 | struct xfrm_algo_desc *aalg_desc; | 345 | struct xfrm_algo_desc *aalg_desc; |
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c index 5d22ca3cca2e..6b7294047238 100644 --- a/net/ipv6/anycast.c +++ b/net/ipv6/anycast.c | |||
@@ -337,7 +337,7 @@ int ipv6_dev_ac_inc(struct net_device *dev, struct in6_addr *addr) | |||
337 | write_unlock_bh(&idev->lock); | 337 | write_unlock_bh(&idev->lock); |
338 | 338 | ||
339 | dst_hold(&rt->u.dst); | 339 | dst_hold(&rt->u.dst); |
340 | if (ip6_ins_rt(rt, NULL, NULL)) | 340 | if (ip6_ins_rt(rt, NULL, NULL, NULL)) |
341 | dst_release(&rt->u.dst); | 341 | dst_release(&rt->u.dst); |
342 | 342 | ||
343 | addrconf_join_solict(dev, &aca->aca_addr); | 343 | addrconf_join_solict(dev, &aca->aca_addr); |
@@ -380,7 +380,7 @@ int __ipv6_dev_ac_dec(struct inet6_dev *idev, struct in6_addr *addr) | |||
380 | addrconf_leave_solict(idev, &aca->aca_addr); | 380 | addrconf_leave_solict(idev, &aca->aca_addr); |
381 | 381 | ||
382 | dst_hold(&aca->aca_rt->u.dst); | 382 | dst_hold(&aca->aca_rt->u.dst); |
383 | if (ip6_del_rt(aca->aca_rt, NULL, NULL)) | 383 | if (ip6_del_rt(aca->aca_rt, NULL, NULL, NULL)) |
384 | dst_free(&aca->aca_rt->u.dst); | 384 | dst_free(&aca->aca_rt->u.dst); |
385 | else | 385 | else |
386 | dst_release(&aca->aca_rt->u.dst); | 386 | dst_release(&aca->aca_rt->u.dst); |
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index be7095d6babe..324db62515a2 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c | |||
@@ -296,7 +296,7 @@ static void esp6_destroy(struct xfrm_state *x) | |||
296 | kfree(esp); | 296 | kfree(esp); |
297 | } | 297 | } |
298 | 298 | ||
299 | static int esp6_init_state(struct xfrm_state *x, void *args) | 299 | static int esp6_init_state(struct xfrm_state *x) |
300 | { | 300 | { |
301 | struct esp_data *esp = NULL; | 301 | struct esp_data *esp = NULL; |
302 | 302 | ||
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 405740b75abb..1b354aa97934 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c | |||
@@ -394,7 +394,7 @@ insert_above: | |||
394 | */ | 394 | */ |
395 | 395 | ||
396 | static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, | 396 | static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, |
397 | struct nlmsghdr *nlh) | 397 | struct nlmsghdr *nlh, struct netlink_skb_parms *req) |
398 | { | 398 | { |
399 | struct rt6_info *iter = NULL; | 399 | struct rt6_info *iter = NULL; |
400 | struct rt6_info **ins; | 400 | struct rt6_info **ins; |
@@ -449,7 +449,7 @@ out: | |||
449 | *ins = rt; | 449 | *ins = rt; |
450 | rt->rt6i_node = fn; | 450 | rt->rt6i_node = fn; |
451 | atomic_inc(&rt->rt6i_ref); | 451 | atomic_inc(&rt->rt6i_ref); |
452 | inet6_rt_notify(RTM_NEWROUTE, rt, nlh); | 452 | inet6_rt_notify(RTM_NEWROUTE, rt, nlh, req); |
453 | rt6_stats.fib_rt_entries++; | 453 | rt6_stats.fib_rt_entries++; |
454 | 454 | ||
455 | if ((fn->fn_flags & RTN_RTINFO) == 0) { | 455 | if ((fn->fn_flags & RTN_RTINFO) == 0) { |
@@ -479,7 +479,8 @@ void fib6_force_start_gc(void) | |||
479 | * with source addr info in sub-trees | 479 | * with source addr info in sub-trees |
480 | */ | 480 | */ |
481 | 481 | ||
482 | int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr) | 482 | int fib6_add(struct fib6_node *root, struct rt6_info *rt, |
483 | struct nlmsghdr *nlh, void *_rtattr, struct netlink_skb_parms *req) | ||
483 | { | 484 | { |
484 | struct fib6_node *fn; | 485 | struct fib6_node *fn; |
485 | int err = -ENOMEM; | 486 | int err = -ENOMEM; |
@@ -552,7 +553,7 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nlmsghdr *nlh, | |||
552 | } | 553 | } |
553 | #endif | 554 | #endif |
554 | 555 | ||
555 | err = fib6_add_rt2node(fn, rt, nlh); | 556 | err = fib6_add_rt2node(fn, rt, nlh, req); |
556 | 557 | ||
557 | if (err == 0) { | 558 | if (err == 0) { |
558 | fib6_start_gc(rt); | 559 | fib6_start_gc(rt); |
@@ -859,7 +860,7 @@ static struct fib6_node * fib6_repair_tree(struct fib6_node *fn) | |||
859 | } | 860 | } |
860 | 861 | ||
861 | static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp, | 862 | static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp, |
862 | struct nlmsghdr *nlh, void *_rtattr) | 863 | struct nlmsghdr *nlh, void *_rtattr, struct netlink_skb_parms *req) |
863 | { | 864 | { |
864 | struct fib6_walker_t *w; | 865 | struct fib6_walker_t *w; |
865 | struct rt6_info *rt = *rtp; | 866 | struct rt6_info *rt = *rtp; |
@@ -915,11 +916,11 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp, | |||
915 | if (atomic_read(&rt->rt6i_ref) != 1) BUG(); | 916 | if (atomic_read(&rt->rt6i_ref) != 1) BUG(); |
916 | } | 917 | } |
917 | 918 | ||
918 | inet6_rt_notify(RTM_DELROUTE, rt, nlh); | 919 | inet6_rt_notify(RTM_DELROUTE, rt, nlh, req); |
919 | rt6_release(rt); | 920 | rt6_release(rt); |
920 | } | 921 | } |
921 | 922 | ||
922 | int fib6_del(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr) | 923 | int fib6_del(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr, struct netlink_skb_parms *req) |
923 | { | 924 | { |
924 | struct fib6_node *fn = rt->rt6i_node; | 925 | struct fib6_node *fn = rt->rt6i_node; |
925 | struct rt6_info **rtp; | 926 | struct rt6_info **rtp; |
@@ -944,7 +945,7 @@ int fib6_del(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr) | |||
944 | 945 | ||
945 | for (rtp = &fn->leaf; *rtp; rtp = &(*rtp)->u.next) { | 946 | for (rtp = &fn->leaf; *rtp; rtp = &(*rtp)->u.next) { |
946 | if (*rtp == rt) { | 947 | if (*rtp == rt) { |
947 | fib6_del_route(fn, rtp, nlh, _rtattr); | 948 | fib6_del_route(fn, rtp, nlh, _rtattr, req); |
948 | return 0; | 949 | return 0; |
949 | } | 950 | } |
950 | } | 951 | } |
@@ -1073,7 +1074,7 @@ static int fib6_clean_node(struct fib6_walker_t *w) | |||
1073 | res = c->func(rt, c->arg); | 1074 | res = c->func(rt, c->arg); |
1074 | if (res < 0) { | 1075 | if (res < 0) { |
1075 | w->leaf = rt; | 1076 | w->leaf = rt; |
1076 | res = fib6_del(rt, NULL, NULL); | 1077 | res = fib6_del(rt, NULL, NULL, NULL); |
1077 | if (res) { | 1078 | if (res) { |
1078 | #if RT6_DEBUG >= 2 | 1079 | #if RT6_DEBUG >= 2 |
1079 | printk(KERN_DEBUG "fib6_clean_node: del failed: rt=%p@%p err=%d\n", rt, rt->rt6i_node, res); | 1080 | printk(KERN_DEBUG "fib6_clean_node: del failed: rt=%p@%p err=%d\n", rt, rt->rt6i_node, res); |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index b78a53586804..06e7cdaeedc5 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -484,9 +484,6 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from) | |||
484 | to->nf_bridge = from->nf_bridge; | 484 | to->nf_bridge = from->nf_bridge; |
485 | nf_bridge_get(to->nf_bridge); | 485 | nf_bridge_get(to->nf_bridge); |
486 | #endif | 486 | #endif |
487 | #ifdef CONFIG_NETFILTER_DEBUG | ||
488 | to->nf_debug = from->nf_debug; | ||
489 | #endif | ||
490 | #endif | 487 | #endif |
491 | } | 488 | } |
492 | 489 | ||
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c index 6cde5310cd76..423feb46ccc0 100644 --- a/net/ipv6/ipcomp6.c +++ b/net/ipv6/ipcomp6.c | |||
@@ -234,14 +234,9 @@ static struct xfrm_state *ipcomp6_tunnel_create(struct xfrm_state *x) | |||
234 | t->props.mode = 1; | 234 | t->props.mode = 1; |
235 | memcpy(t->props.saddr.a6, x->props.saddr.a6, sizeof(struct in6_addr)); | 235 | memcpy(t->props.saddr.a6, x->props.saddr.a6, sizeof(struct in6_addr)); |
236 | 236 | ||
237 | t->type = xfrm_get_type(IPPROTO_IPV6, t->props.family); | 237 | if (xfrm_init_state(t)) |
238 | if (t->type == NULL) | ||
239 | goto error; | 238 | goto error; |
240 | 239 | ||
241 | if (t->type->init_state(t, NULL)) | ||
242 | goto error; | ||
243 | |||
244 | t->km.state = XFRM_STATE_VALID; | ||
245 | atomic_set(&t->tunnel_users, 1); | 240 | atomic_set(&t->tunnel_users, 1); |
246 | 241 | ||
247 | out: | 242 | out: |
@@ -420,7 +415,7 @@ static void ipcomp6_destroy(struct xfrm_state *x) | |||
420 | xfrm6_tunnel_free_spi((xfrm_address_t *)&x->props.saddr); | 415 | xfrm6_tunnel_free_spi((xfrm_address_t *)&x->props.saddr); |
421 | } | 416 | } |
422 | 417 | ||
423 | static int ipcomp6_init_state(struct xfrm_state *x, void *args) | 418 | static int ipcomp6_init_state(struct xfrm_state *x) |
424 | { | 419 | { |
425 | int err; | 420 | int err; |
426 | struct ipcomp_data *ipcd; | 421 | struct ipcomp_data *ipcd; |
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 279ab86be662..f3ef4c38d315 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c | |||
@@ -423,11 +423,12 @@ done: | |||
423 | psin6 = (struct sockaddr_in6 *)&greqs.gsr_group; | 423 | psin6 = (struct sockaddr_in6 *)&greqs.gsr_group; |
424 | retv = ipv6_sock_mc_join(sk, greqs.gsr_interface, | 424 | retv = ipv6_sock_mc_join(sk, greqs.gsr_interface, |
425 | &psin6->sin6_addr); | 425 | &psin6->sin6_addr); |
426 | if (retv) | 426 | /* prior join w/ different source is ok */ |
427 | if (retv && retv != -EADDRINUSE) | ||
427 | break; | 428 | break; |
428 | omode = MCAST_INCLUDE; | 429 | omode = MCAST_INCLUDE; |
429 | add = 1; | 430 | add = 1; |
430 | } else /*IP_DROP_SOURCE_MEMBERSHIP */ { | 431 | } else /* MCAST_LEAVE_SOURCE_GROUP */ { |
431 | omode = MCAST_INCLUDE; | 432 | omode = MCAST_INCLUDE; |
432 | add = 0; | 433 | add = 0; |
433 | } | 434 | } |
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 393b6e6f50a9..562fcd14fdea 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c | |||
@@ -188,6 +188,16 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, struct in6_addr *addr) | |||
188 | if (!ipv6_addr_is_multicast(addr)) | 188 | if (!ipv6_addr_is_multicast(addr)) |
189 | return -EINVAL; | 189 | return -EINVAL; |
190 | 190 | ||
191 | read_lock_bh(&ipv6_sk_mc_lock); | ||
192 | for (mc_lst=np->ipv6_mc_list; mc_lst; mc_lst=mc_lst->next) { | ||
193 | if ((ifindex == 0 || mc_lst->ifindex == ifindex) && | ||
194 | ipv6_addr_equal(&mc_lst->addr, addr)) { | ||
195 | read_unlock_bh(&ipv6_sk_mc_lock); | ||
196 | return -EADDRINUSE; | ||
197 | } | ||
198 | } | ||
199 | read_unlock_bh(&ipv6_sk_mc_lock); | ||
200 | |||
191 | mc_lst = sock_kmalloc(sk, sizeof(struct ipv6_mc_socklist), GFP_KERNEL); | 201 | mc_lst = sock_kmalloc(sk, sizeof(struct ipv6_mc_socklist), GFP_KERNEL); |
192 | 202 | ||
193 | if (mc_lst == NULL) | 203 | if (mc_lst == NULL) |
@@ -349,6 +359,7 @@ int ip6_mc_source(int add, int omode, struct sock *sk, | |||
349 | struct ipv6_pinfo *inet6 = inet6_sk(sk); | 359 | struct ipv6_pinfo *inet6 = inet6_sk(sk); |
350 | struct ip6_sf_socklist *psl; | 360 | struct ip6_sf_socklist *psl; |
351 | int i, j, rv; | 361 | int i, j, rv; |
362 | int leavegroup = 0; | ||
352 | int err; | 363 | int err; |
353 | 364 | ||
354 | if (pgsr->gsr_group.ss_family != AF_INET6 || | 365 | if (pgsr->gsr_group.ss_family != AF_INET6 || |
@@ -368,6 +379,7 @@ int ip6_mc_source(int add, int omode, struct sock *sk, | |||
368 | 379 | ||
369 | err = -EADDRNOTAVAIL; | 380 | err = -EADDRNOTAVAIL; |
370 | 381 | ||
382 | read_lock_bh(&ipv6_sk_mc_lock); | ||
371 | for (pmc=inet6->ipv6_mc_list; pmc; pmc=pmc->next) { | 383 | for (pmc=inet6->ipv6_mc_list; pmc; pmc=pmc->next) { |
372 | if (pgsr->gsr_interface && pmc->ifindex != pgsr->gsr_interface) | 384 | if (pgsr->gsr_interface && pmc->ifindex != pgsr->gsr_interface) |
373 | continue; | 385 | continue; |
@@ -401,6 +413,12 @@ int ip6_mc_source(int add, int omode, struct sock *sk, | |||
401 | if (rv) /* source not found */ | 413 | if (rv) /* source not found */ |
402 | goto done; | 414 | goto done; |
403 | 415 | ||
416 | /* special case - (INCLUDE, empty) == LEAVE_GROUP */ | ||
417 | if (psl->sl_count == 1 && omode == MCAST_INCLUDE) { | ||
418 | leavegroup = 1; | ||
419 | goto done; | ||
420 | } | ||
421 | |||
404 | /* update the interface filter */ | 422 | /* update the interface filter */ |
405 | ip6_mc_del_src(idev, group, omode, 1, source, 1); | 423 | ip6_mc_del_src(idev, group, omode, 1, source, 1); |
406 | 424 | ||
@@ -453,9 +471,12 @@ int ip6_mc_source(int add, int omode, struct sock *sk, | |||
453 | /* update the interface list */ | 471 | /* update the interface list */ |
454 | ip6_mc_add_src(idev, group, omode, 1, source, 1); | 472 | ip6_mc_add_src(idev, group, omode, 1, source, 1); |
455 | done: | 473 | done: |
474 | read_unlock_bh(&ipv6_sk_mc_lock); | ||
456 | read_unlock_bh(&idev->lock); | 475 | read_unlock_bh(&idev->lock); |
457 | in6_dev_put(idev); | 476 | in6_dev_put(idev); |
458 | dev_put(dev); | 477 | dev_put(dev); |
478 | if (leavegroup) | ||
479 | return ipv6_sock_mc_drop(sk, pgsr->gsr_interface, group); | ||
459 | return err; | 480 | return err; |
460 | } | 481 | } |
461 | 482 | ||
@@ -1280,15 +1301,6 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size) | |||
1280 | return NULL; | 1301 | return NULL; |
1281 | 1302 | ||
1282 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); | 1303 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); |
1283 | if (dev->hard_header) { | ||
1284 | unsigned char ha[MAX_ADDR_LEN]; | ||
1285 | |||
1286 | ndisc_mc_map(&mld2_all_mcr, ha, dev, 1); | ||
1287 | if (dev->hard_header(skb, dev, ETH_P_IPV6,ha,NULL,size) < 0) { | ||
1288 | kfree_skb(skb); | ||
1289 | return NULL; | ||
1290 | } | ||
1291 | } | ||
1292 | 1304 | ||
1293 | if (ipv6_get_lladdr(dev, &addr_buf)) { | 1305 | if (ipv6_get_lladdr(dev, &addr_buf)) { |
1294 | /* <draft-ietf-magma-mld-source-05.txt>: | 1306 | /* <draft-ietf-magma-mld-source-05.txt>: |
@@ -1312,6 +1324,30 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size) | |||
1312 | return skb; | 1324 | return skb; |
1313 | } | 1325 | } |
1314 | 1326 | ||
1327 | static inline int mld_dev_queue_xmit2(struct sk_buff *skb) | ||
1328 | { | ||
1329 | struct net_device *dev = skb->dev; | ||
1330 | |||
1331 | if (dev->hard_header) { | ||
1332 | unsigned char ha[MAX_ADDR_LEN]; | ||
1333 | int err; | ||
1334 | |||
1335 | ndisc_mc_map(&skb->nh.ipv6h->daddr, ha, dev, 1); | ||
1336 | err = dev->hard_header(skb, dev, ETH_P_IPV6, ha, NULL, skb->len); | ||
1337 | if (err < 0) { | ||
1338 | kfree_skb(skb); | ||
1339 | return err; | ||
1340 | } | ||
1341 | } | ||
1342 | return dev_queue_xmit(skb); | ||
1343 | } | ||
1344 | |||
1345 | static inline int mld_dev_queue_xmit(struct sk_buff *skb) | ||
1346 | { | ||
1347 | return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb, NULL, skb->dev, | ||
1348 | mld_dev_queue_xmit2); | ||
1349 | } | ||
1350 | |||
1315 | static void mld_sendpack(struct sk_buff *skb) | 1351 | static void mld_sendpack(struct sk_buff *skb) |
1316 | { | 1352 | { |
1317 | struct ipv6hdr *pip6 = skb->nh.ipv6h; | 1353 | struct ipv6hdr *pip6 = skb->nh.ipv6h; |
@@ -1329,7 +1365,7 @@ static void mld_sendpack(struct sk_buff *skb) | |||
1329 | pmr->csum = csum_ipv6_magic(&pip6->saddr, &pip6->daddr, mldlen, | 1365 | pmr->csum = csum_ipv6_magic(&pip6->saddr, &pip6->daddr, mldlen, |
1330 | IPPROTO_ICMPV6, csum_partial(skb->h.raw, mldlen, 0)); | 1366 | IPPROTO_ICMPV6, csum_partial(skb->h.raw, mldlen, 0)); |
1331 | err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev, | 1367 | err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev, |
1332 | dev_queue_xmit); | 1368 | mld_dev_queue_xmit); |
1333 | if (!err) { | 1369 | if (!err) { |
1334 | ICMP6_INC_STATS(idev,ICMP6_MIB_OUTMSGS); | 1370 | ICMP6_INC_STATS(idev,ICMP6_MIB_OUTMSGS); |
1335 | IP6_INC_STATS(IPSTATS_MIB_OUTMCASTPKTS); | 1371 | IP6_INC_STATS(IPSTATS_MIB_OUTMCASTPKTS); |
@@ -1635,12 +1671,6 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) | |||
1635 | } | 1671 | } |
1636 | 1672 | ||
1637 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); | 1673 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); |
1638 | if (dev->hard_header) { | ||
1639 | unsigned char ha[MAX_ADDR_LEN]; | ||
1640 | ndisc_mc_map(snd_addr, ha, dev, 1); | ||
1641 | if (dev->hard_header(skb, dev, ETH_P_IPV6, ha, NULL, full_len) < 0) | ||
1642 | goto out; | ||
1643 | } | ||
1644 | 1674 | ||
1645 | if (ipv6_get_lladdr(dev, &addr_buf)) { | 1675 | if (ipv6_get_lladdr(dev, &addr_buf)) { |
1646 | /* <draft-ietf-magma-mld-source-05.txt>: | 1676 | /* <draft-ietf-magma-mld-source-05.txt>: |
@@ -1668,7 +1698,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) | |||
1668 | idev = in6_dev_get(skb->dev); | 1698 | idev = in6_dev_get(skb->dev); |
1669 | 1699 | ||
1670 | err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev, | 1700 | err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev, |
1671 | dev_queue_xmit); | 1701 | mld_dev_queue_xmit); |
1672 | if (!err) { | 1702 | if (!err) { |
1673 | if (type == ICMPV6_MGM_REDUCTION) | 1703 | if (type == ICMPV6_MGM_REDUCTION) |
1674 | ICMP6_INC_STATS(idev, ICMP6_MIB_OUTGROUPMEMBREDUCTIONS); | 1704 | ICMP6_INC_STATS(idev, ICMP6_MIB_OUTGROUPMEMBREDUCTIONS); |
@@ -1682,10 +1712,6 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) | |||
1682 | if (likely(idev != NULL)) | 1712 | if (likely(idev != NULL)) |
1683 | in6_dev_put(idev); | 1713 | in6_dev_put(idev); |
1684 | return; | 1714 | return; |
1685 | |||
1686 | out: | ||
1687 | IP6_INC_STATS(IPSTATS_MIB_OUTDISCARDS); | ||
1688 | kfree_skb(skb); | ||
1689 | } | 1715 | } |
1690 | 1716 | ||
1691 | static int ip6_mc_del1_src(struct ifmcaddr6 *pmc, int sfmode, | 1717 | static int ip6_mc_del1_src(struct ifmcaddr6 *pmc, int sfmode, |
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 7c291f4e9edc..7ae72d4c9bd2 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
@@ -955,7 +955,7 @@ static void ndisc_recv_na(struct sk_buff *skb) | |||
955 | struct rt6_info *rt; | 955 | struct rt6_info *rt; |
956 | rt = rt6_get_dflt_router(saddr, dev); | 956 | rt = rt6_get_dflt_router(saddr, dev); |
957 | if (rt) | 957 | if (rt) |
958 | ip6_del_rt(rt, NULL, NULL); | 958 | ip6_del_rt(rt, NULL, NULL, NULL); |
959 | } | 959 | } |
960 | 960 | ||
961 | out: | 961 | out: |
@@ -1096,7 +1096,7 @@ static void ndisc_router_discovery(struct sk_buff *skb) | |||
1096 | 1096 | ||
1097 | if (rt && lifetime == 0) { | 1097 | if (rt && lifetime == 0) { |
1098 | neigh_clone(neigh); | 1098 | neigh_clone(neigh); |
1099 | ip6_del_rt(rt, NULL, NULL); | 1099 | ip6_del_rt(rt, NULL, NULL, NULL); |
1100 | rt = NULL; | 1100 | rt = NULL; |
1101 | } | 1101 | } |
1102 | 1102 | ||
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index c735276fdd5f..73034511c8db 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
@@ -71,7 +71,6 @@ static DECLARE_MUTEX(ip6t_mutex); | |||
71 | /* Must have mutex */ | 71 | /* Must have mutex */ |
72 | #define ASSERT_READ_LOCK(x) IP_NF_ASSERT(down_trylock(&ip6t_mutex) != 0) | 72 | #define ASSERT_READ_LOCK(x) IP_NF_ASSERT(down_trylock(&ip6t_mutex) != 0) |
73 | #define ASSERT_WRITE_LOCK(x) IP_NF_ASSERT(down_trylock(&ip6t_mutex) != 0) | 73 | #define ASSERT_WRITE_LOCK(x) IP_NF_ASSERT(down_trylock(&ip6t_mutex) != 0) |
74 | #include <linux/netfilter_ipv4/lockhelp.h> | ||
75 | #include <linux/netfilter_ipv4/listhelp.h> | 74 | #include <linux/netfilter_ipv4/listhelp.h> |
76 | 75 | ||
77 | #if 0 | 76 | #if 0 |
diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c index bfc3d0185d19..c44685e391b7 100644 --- a/net/ipv6/netfilter/ip6t_LOG.c +++ b/net/ipv6/netfilter/ip6t_LOG.c | |||
@@ -366,8 +366,6 @@ ip6t_log_packet(unsigned int hooknum, | |||
366 | const char *level_string, | 366 | const char *level_string, |
367 | const char *prefix) | 367 | const char *prefix) |
368 | { | 368 | { |
369 | struct ipv6hdr *ipv6h = skb->nh.ipv6h; | ||
370 | |||
371 | spin_lock_bh(&log_lock); | 369 | spin_lock_bh(&log_lock); |
372 | printk(level_string); | 370 | printk(level_string); |
373 | printk("%sIN=%s OUT=%s ", | 371 | printk("%sIN=%s OUT=%s ", |
@@ -377,39 +375,25 @@ ip6t_log_packet(unsigned int hooknum, | |||
377 | if (in && !out) { | 375 | if (in && !out) { |
378 | /* MAC logging for input chain only. */ | 376 | /* MAC logging for input chain only. */ |
379 | printk("MAC="); | 377 | printk("MAC="); |
380 | if (skb->dev && skb->dev->hard_header_len && skb->mac.raw != (void*)ipv6h) { | 378 | if (skb->dev && skb->dev->hard_header_len && |
381 | if (skb->dev->type != ARPHRD_SIT){ | 379 | skb->mac.raw != skb->nh.raw) { |
382 | int i; | 380 | unsigned char *p = skb->mac.raw; |
383 | unsigned char *p = skb->mac.raw; | 381 | int i; |
384 | for (i = 0; i < skb->dev->hard_header_len; i++,p++) | 382 | |
385 | printk("%02x%c", *p, | 383 | if (skb->dev->type == ARPHRD_SIT && |
386 | i==skb->dev->hard_header_len - 1 | 384 | (p -= ETH_HLEN) < skb->head) |
387 | ? ' ':':'); | 385 | p = NULL; |
388 | } else { | 386 | |
389 | int i; | 387 | if (p != NULL) |
390 | unsigned char *p = skb->mac.raw; | 388 | for (i = 0; i < skb->dev->hard_header_len; i++) |
391 | if ( p - (ETH_ALEN*2+2) > skb->head ){ | 389 | printk("%02x", p[i]); |
392 | p -= (ETH_ALEN+2); | 390 | printk(" "); |
393 | for (i = 0; i < (ETH_ALEN); i++,p++) | 391 | |
394 | printk("%02x%s", *p, | 392 | if (skb->dev->type == ARPHRD_SIT) { |
395 | i == ETH_ALEN-1 ? "->" : ":"); | 393 | struct iphdr *iph = (struct iphdr *)skb->mac.raw; |
396 | p -= (ETH_ALEN*2); | 394 | printk("TUNNEL=%u.%u.%u.%u->%u.%u.%u.%u ", |
397 | for (i = 0; i < (ETH_ALEN); i++,p++) | 395 | NIPQUAD(iph->saddr), |
398 | printk("%02x%c", *p, | 396 | NIPQUAD(iph->daddr)); |
399 | i == ETH_ALEN-1 ? ' ' : ':'); | ||
400 | } | ||
401 | |||
402 | if ((skb->dev->addr_len == 4) && | ||
403 | skb->dev->hard_header_len > 20){ | ||
404 | printk("TUNNEL="); | ||
405 | p = skb->mac.raw + 12; | ||
406 | for (i = 0; i < 4; i++,p++) | ||
407 | printk("%3d%s", *p, | ||
408 | i == 3 ? "->" : "."); | ||
409 | for (i = 0; i < 4; i++,p++) | ||
410 | printk("%3d%c", *p, | ||
411 | i == 3 ? ' ' : '.'); | ||
412 | } | ||
413 | } | 397 | } |
414 | } else | 398 | } else |
415 | printk(" "); | 399 | printk(" "); |
diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c index 71407beaf790..c2982efd14af 100644 --- a/net/ipv6/netfilter/ip6table_raw.c +++ b/net/ipv6/netfilter/ip6table_raw.c | |||
@@ -129,13 +129,15 @@ static struct nf_hook_ops ip6t_ops[] = { | |||
129 | .hook = ip6t_hook, | 129 | .hook = ip6t_hook, |
130 | .pf = PF_INET6, | 130 | .pf = PF_INET6, |
131 | .hooknum = NF_IP6_PRE_ROUTING, | 131 | .hooknum = NF_IP6_PRE_ROUTING, |
132 | .priority = NF_IP6_PRI_FIRST | 132 | .priority = NF_IP6_PRI_FIRST, |
133 | .owner = THIS_MODULE, | ||
133 | }, | 134 | }, |
134 | { | 135 | { |
135 | .hook = ip6t_hook, | 136 | .hook = ip6t_hook, |
136 | .pf = PF_INET6, | 137 | .pf = PF_INET6, |
137 | .hooknum = NF_IP6_LOCAL_OUT, | 138 | .hooknum = NF_IP6_LOCAL_OUT, |
138 | .priority = NF_IP6_PRI_FIRST | 139 | .priority = NF_IP6_PRI_FIRST, |
140 | .owner = THIS_MODULE, | ||
139 | }, | 141 | }, |
140 | }; | 142 | }; |
141 | 143 | ||
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 1f5b226c3573..878789b3122d 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -384,12 +384,13 @@ struct rt6_info *rt6_lookup(struct in6_addr *daddr, struct in6_addr *saddr, | |||
384 | be destroyed. | 384 | be destroyed. |
385 | */ | 385 | */ |
386 | 386 | ||
387 | int ip6_ins_rt(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr) | 387 | int ip6_ins_rt(struct rt6_info *rt, struct nlmsghdr *nlh, |
388 | void *_rtattr, struct netlink_skb_parms *req) | ||
388 | { | 389 | { |
389 | int err; | 390 | int err; |
390 | 391 | ||
391 | write_lock_bh(&rt6_lock); | 392 | write_lock_bh(&rt6_lock); |
392 | err = fib6_add(&ip6_routing_table, rt, nlh, _rtattr); | 393 | err = fib6_add(&ip6_routing_table, rt, nlh, _rtattr, req); |
393 | write_unlock_bh(&rt6_lock); | 394 | write_unlock_bh(&rt6_lock); |
394 | 395 | ||
395 | return err; | 396 | return err; |
@@ -400,7 +401,7 @@ int ip6_ins_rt(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr) | |||
400 | */ | 401 | */ |
401 | 402 | ||
402 | static struct rt6_info *rt6_cow(struct rt6_info *ort, struct in6_addr *daddr, | 403 | static struct rt6_info *rt6_cow(struct rt6_info *ort, struct in6_addr *daddr, |
403 | struct in6_addr *saddr) | 404 | struct in6_addr *saddr, struct netlink_skb_parms *req) |
404 | { | 405 | { |
405 | int err; | 406 | int err; |
406 | struct rt6_info *rt; | 407 | struct rt6_info *rt; |
@@ -432,7 +433,7 @@ static struct rt6_info *rt6_cow(struct rt6_info *ort, struct in6_addr *daddr, | |||
432 | 433 | ||
433 | dst_hold(&rt->u.dst); | 434 | dst_hold(&rt->u.dst); |
434 | 435 | ||
435 | err = ip6_ins_rt(rt, NULL, NULL); | 436 | err = ip6_ins_rt(rt, NULL, NULL, req); |
436 | if (err == 0) | 437 | if (err == 0) |
437 | return rt; | 438 | return rt; |
438 | 439 | ||
@@ -491,7 +492,8 @@ restart: | |||
491 | read_unlock_bh(&rt6_lock); | 492 | read_unlock_bh(&rt6_lock); |
492 | 493 | ||
493 | nrt = rt6_cow(rt, &skb->nh.ipv6h->daddr, | 494 | nrt = rt6_cow(rt, &skb->nh.ipv6h->daddr, |
494 | &skb->nh.ipv6h->saddr); | 495 | &skb->nh.ipv6h->saddr, |
496 | &NETLINK_CB(skb)); | ||
495 | 497 | ||
496 | dst_release(&rt->u.dst); | 498 | dst_release(&rt->u.dst); |
497 | rt = nrt; | 499 | rt = nrt; |
@@ -551,7 +553,7 @@ restart: | |||
551 | dst_hold(&rt->u.dst); | 553 | dst_hold(&rt->u.dst); |
552 | read_unlock_bh(&rt6_lock); | 554 | read_unlock_bh(&rt6_lock); |
553 | 555 | ||
554 | nrt = rt6_cow(rt, &fl->fl6_dst, &fl->fl6_src); | 556 | nrt = rt6_cow(rt, &fl->fl6_dst, &fl->fl6_src, NULL); |
555 | 557 | ||
556 | dst_release(&rt->u.dst); | 558 | dst_release(&rt->u.dst); |
557 | rt = nrt; | 559 | rt = nrt; |
@@ -598,7 +600,7 @@ static struct dst_entry *ip6_negative_advice(struct dst_entry *dst) | |||
598 | 600 | ||
599 | if (rt) { | 601 | if (rt) { |
600 | if (rt->rt6i_flags & RTF_CACHE) | 602 | if (rt->rt6i_flags & RTF_CACHE) |
601 | ip6_del_rt(rt, NULL, NULL); | 603 | ip6_del_rt(rt, NULL, NULL, NULL); |
602 | else | 604 | else |
603 | dst_release(dst); | 605 | dst_release(dst); |
604 | } | 606 | } |
@@ -787,7 +789,8 @@ int ipv6_get_hoplimit(struct net_device *dev) | |||
787 | * | 789 | * |
788 | */ | 790 | */ |
789 | 791 | ||
790 | int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_rtattr) | 792 | int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, |
793 | void *_rtattr, struct netlink_skb_parms *req) | ||
791 | { | 794 | { |
792 | int err; | 795 | int err; |
793 | struct rtmsg *r; | 796 | struct rtmsg *r; |
@@ -974,7 +977,7 @@ install_route: | |||
974 | rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_mtu(&rt->u.dst)); | 977 | rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_mtu(&rt->u.dst)); |
975 | rt->u.dst.dev = dev; | 978 | rt->u.dst.dev = dev; |
976 | rt->rt6i_idev = idev; | 979 | rt->rt6i_idev = idev; |
977 | return ip6_ins_rt(rt, nlh, _rtattr); | 980 | return ip6_ins_rt(rt, nlh, _rtattr, req); |
978 | 981 | ||
979 | out: | 982 | out: |
980 | if (dev) | 983 | if (dev) |
@@ -986,7 +989,7 @@ out: | |||
986 | return err; | 989 | return err; |
987 | } | 990 | } |
988 | 991 | ||
989 | int ip6_del_rt(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr) | 992 | int ip6_del_rt(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr, struct netlink_skb_parms *req) |
990 | { | 993 | { |
991 | int err; | 994 | int err; |
992 | 995 | ||
@@ -994,7 +997,7 @@ int ip6_del_rt(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr) | |||
994 | 997 | ||
995 | rt6_reset_dflt_pointer(NULL); | 998 | rt6_reset_dflt_pointer(NULL); |
996 | 999 | ||
997 | err = fib6_del(rt, nlh, _rtattr); | 1000 | err = fib6_del(rt, nlh, _rtattr, req); |
998 | dst_release(&rt->u.dst); | 1001 | dst_release(&rt->u.dst); |
999 | 1002 | ||
1000 | write_unlock_bh(&rt6_lock); | 1003 | write_unlock_bh(&rt6_lock); |
@@ -1002,7 +1005,7 @@ int ip6_del_rt(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr) | |||
1002 | return err; | 1005 | return err; |
1003 | } | 1006 | } |
1004 | 1007 | ||
1005 | static int ip6_route_del(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_rtattr) | 1008 | static int ip6_route_del(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_rtattr, struct netlink_skb_parms *req) |
1006 | { | 1009 | { |
1007 | struct fib6_node *fn; | 1010 | struct fib6_node *fn; |
1008 | struct rt6_info *rt; | 1011 | struct rt6_info *rt; |
@@ -1029,7 +1032,7 @@ static int ip6_route_del(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_r | |||
1029 | dst_hold(&rt->u.dst); | 1032 | dst_hold(&rt->u.dst); |
1030 | read_unlock_bh(&rt6_lock); | 1033 | read_unlock_bh(&rt6_lock); |
1031 | 1034 | ||
1032 | return ip6_del_rt(rt, nlh, _rtattr); | 1035 | return ip6_del_rt(rt, nlh, _rtattr, req); |
1033 | } | 1036 | } |
1034 | } | 1037 | } |
1035 | read_unlock_bh(&rt6_lock); | 1038 | read_unlock_bh(&rt6_lock); |
@@ -1136,11 +1139,11 @@ source_ok: | |||
1136 | nrt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(neigh->dev); | 1139 | nrt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(neigh->dev); |
1137 | nrt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_mtu(&nrt->u.dst)); | 1140 | nrt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_mtu(&nrt->u.dst)); |
1138 | 1141 | ||
1139 | if (ip6_ins_rt(nrt, NULL, NULL)) | 1142 | if (ip6_ins_rt(nrt, NULL, NULL, NULL)) |
1140 | goto out; | 1143 | goto out; |
1141 | 1144 | ||
1142 | if (rt->rt6i_flags&RTF_CACHE) { | 1145 | if (rt->rt6i_flags&RTF_CACHE) { |
1143 | ip6_del_rt(rt, NULL, NULL); | 1146 | ip6_del_rt(rt, NULL, NULL, NULL); |
1144 | return; | 1147 | return; |
1145 | } | 1148 | } |
1146 | 1149 | ||
@@ -1204,7 +1207,7 @@ void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr, | |||
1204 | 2. It is gatewayed route or NONEXTHOP route. Action: clone it. | 1207 | 2. It is gatewayed route or NONEXTHOP route. Action: clone it. |
1205 | */ | 1208 | */ |
1206 | if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP)) { | 1209 | if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP)) { |
1207 | nrt = rt6_cow(rt, daddr, saddr); | 1210 | nrt = rt6_cow(rt, daddr, saddr, NULL); |
1208 | if (!nrt->u.dst.error) { | 1211 | if (!nrt->u.dst.error) { |
1209 | nrt->u.dst.metrics[RTAX_MTU-1] = pmtu; | 1212 | nrt->u.dst.metrics[RTAX_MTU-1] = pmtu; |
1210 | if (allfrag) | 1213 | if (allfrag) |
@@ -1232,7 +1235,7 @@ void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr, | |||
1232 | nrt->u.dst.metrics[RTAX_MTU-1] = pmtu; | 1235 | nrt->u.dst.metrics[RTAX_MTU-1] = pmtu; |
1233 | if (allfrag) | 1236 | if (allfrag) |
1234 | nrt->u.dst.metrics[RTAX_FEATURES-1] |= RTAX_FEATURE_ALLFRAG; | 1237 | nrt->u.dst.metrics[RTAX_FEATURES-1] |= RTAX_FEATURE_ALLFRAG; |
1235 | ip6_ins_rt(nrt, NULL, NULL); | 1238 | ip6_ins_rt(nrt, NULL, NULL, NULL); |
1236 | } | 1239 | } |
1237 | 1240 | ||
1238 | out: | 1241 | out: |
@@ -1305,7 +1308,7 @@ struct rt6_info *rt6_add_dflt_router(struct in6_addr *gwaddr, | |||
1305 | 1308 | ||
1306 | rtmsg.rtmsg_ifindex = dev->ifindex; | 1309 | rtmsg.rtmsg_ifindex = dev->ifindex; |
1307 | 1310 | ||
1308 | ip6_route_add(&rtmsg, NULL, NULL); | 1311 | ip6_route_add(&rtmsg, NULL, NULL, NULL); |
1309 | return rt6_get_dflt_router(gwaddr, dev); | 1312 | return rt6_get_dflt_router(gwaddr, dev); |
1310 | } | 1313 | } |
1311 | 1314 | ||
@@ -1323,7 +1326,7 @@ restart: | |||
1323 | 1326 | ||
1324 | read_unlock_bh(&rt6_lock); | 1327 | read_unlock_bh(&rt6_lock); |
1325 | 1328 | ||
1326 | ip6_del_rt(rt, NULL, NULL); | 1329 | ip6_del_rt(rt, NULL, NULL, NULL); |
1327 | 1330 | ||
1328 | goto restart; | 1331 | goto restart; |
1329 | } | 1332 | } |
@@ -1349,10 +1352,10 @@ int ipv6_route_ioctl(unsigned int cmd, void __user *arg) | |||
1349 | rtnl_lock(); | 1352 | rtnl_lock(); |
1350 | switch (cmd) { | 1353 | switch (cmd) { |
1351 | case SIOCADDRT: | 1354 | case SIOCADDRT: |
1352 | err = ip6_route_add(&rtmsg, NULL, NULL); | 1355 | err = ip6_route_add(&rtmsg, NULL, NULL, NULL); |
1353 | break; | 1356 | break; |
1354 | case SIOCDELRT: | 1357 | case SIOCDELRT: |
1355 | err = ip6_route_del(&rtmsg, NULL, NULL); | 1358 | err = ip6_route_del(&rtmsg, NULL, NULL, NULL); |
1356 | break; | 1359 | break; |
1357 | default: | 1360 | default: |
1358 | err = -EINVAL; | 1361 | err = -EINVAL; |
@@ -1546,7 +1549,7 @@ int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
1546 | 1549 | ||
1547 | if (inet6_rtm_to_rtmsg(r, arg, &rtmsg)) | 1550 | if (inet6_rtm_to_rtmsg(r, arg, &rtmsg)) |
1548 | return -EINVAL; | 1551 | return -EINVAL; |
1549 | return ip6_route_del(&rtmsg, nlh, arg); | 1552 | return ip6_route_del(&rtmsg, nlh, arg, &NETLINK_CB(skb)); |
1550 | } | 1553 | } |
1551 | 1554 | ||
1552 | int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | 1555 | int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) |
@@ -1556,7 +1559,7 @@ int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
1556 | 1559 | ||
1557 | if (inet6_rtm_to_rtmsg(r, arg, &rtmsg)) | 1560 | if (inet6_rtm_to_rtmsg(r, arg, &rtmsg)) |
1558 | return -EINVAL; | 1561 | return -EINVAL; |
1559 | return ip6_route_add(&rtmsg, nlh, arg); | 1562 | return ip6_route_add(&rtmsg, nlh, arg, &NETLINK_CB(skb)); |
1560 | } | 1563 | } |
1561 | 1564 | ||
1562 | struct rt6_rtnl_dump_arg | 1565 | struct rt6_rtnl_dump_arg |
@@ -1566,12 +1569,9 @@ struct rt6_rtnl_dump_arg | |||
1566 | }; | 1569 | }; |
1567 | 1570 | ||
1568 | static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, | 1571 | static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, |
1569 | struct in6_addr *dst, | 1572 | struct in6_addr *dst, struct in6_addr *src, |
1570 | struct in6_addr *src, | 1573 | int iif, int type, u32 pid, u32 seq, |
1571 | int iif, | 1574 | int prefix, unsigned int flags) |
1572 | int type, u32 pid, u32 seq, | ||
1573 | struct nlmsghdr *in_nlh, int prefix, | ||
1574 | unsigned int flags) | ||
1575 | { | 1575 | { |
1576 | struct rtmsg *rtm; | 1576 | struct rtmsg *rtm; |
1577 | struct nlmsghdr *nlh; | 1577 | struct nlmsghdr *nlh; |
@@ -1585,10 +1585,6 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, | |||
1585 | } | 1585 | } |
1586 | } | 1586 | } |
1587 | 1587 | ||
1588 | if (!pid && in_nlh) { | ||
1589 | pid = in_nlh->nlmsg_pid; | ||
1590 | } | ||
1591 | |||
1592 | nlh = NLMSG_NEW(skb, pid, seq, type, sizeof(*rtm), flags); | 1588 | nlh = NLMSG_NEW(skb, pid, seq, type, sizeof(*rtm), flags); |
1593 | rtm = NLMSG_DATA(nlh); | 1589 | rtm = NLMSG_DATA(nlh); |
1594 | rtm->rtm_family = AF_INET6; | 1590 | rtm->rtm_family = AF_INET6; |
@@ -1675,7 +1671,7 @@ static int rt6_dump_route(struct rt6_info *rt, void *p_arg) | |||
1675 | 1671 | ||
1676 | return rt6_fill_node(arg->skb, rt, NULL, NULL, 0, RTM_NEWROUTE, | 1672 | return rt6_fill_node(arg->skb, rt, NULL, NULL, 0, RTM_NEWROUTE, |
1677 | NETLINK_CB(arg->cb->skb).pid, arg->cb->nlh->nlmsg_seq, | 1673 | NETLINK_CB(arg->cb->skb).pid, arg->cb->nlh->nlmsg_seq, |
1678 | NULL, prefix, NLM_F_MULTI); | 1674 | prefix, NLM_F_MULTI); |
1679 | } | 1675 | } |
1680 | 1676 | ||
1681 | static int fib6_dump_node(struct fib6_walker_t *w) | 1677 | static int fib6_dump_node(struct fib6_walker_t *w) |
@@ -1823,7 +1819,7 @@ int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg) | |||
1823 | &fl.fl6_dst, &fl.fl6_src, | 1819 | &fl.fl6_dst, &fl.fl6_src, |
1824 | iif, | 1820 | iif, |
1825 | RTM_NEWROUTE, NETLINK_CB(in_skb).pid, | 1821 | RTM_NEWROUTE, NETLINK_CB(in_skb).pid, |
1826 | nlh->nlmsg_seq, nlh, 0, 0); | 1822 | nlh->nlmsg_seq, 0, 0); |
1827 | if (err < 0) { | 1823 | if (err < 0) { |
1828 | err = -EMSGSIZE; | 1824 | err = -EMSGSIZE; |
1829 | goto out_free; | 1825 | goto out_free; |
@@ -1839,17 +1835,25 @@ out_free: | |||
1839 | goto out; | 1835 | goto out; |
1840 | } | 1836 | } |
1841 | 1837 | ||
1842 | void inet6_rt_notify(int event, struct rt6_info *rt, struct nlmsghdr *nlh) | 1838 | void inet6_rt_notify(int event, struct rt6_info *rt, struct nlmsghdr *nlh, |
1839 | struct netlink_skb_parms *req) | ||
1843 | { | 1840 | { |
1844 | struct sk_buff *skb; | 1841 | struct sk_buff *skb; |
1845 | int size = NLMSG_SPACE(sizeof(struct rtmsg)+256); | 1842 | int size = NLMSG_SPACE(sizeof(struct rtmsg)+256); |
1843 | u32 pid = current->pid; | ||
1844 | u32 seq = 0; | ||
1846 | 1845 | ||
1846 | if (req) | ||
1847 | pid = req->pid; | ||
1848 | if (nlh) | ||
1849 | seq = nlh->nlmsg_seq; | ||
1850 | |||
1847 | skb = alloc_skb(size, gfp_any()); | 1851 | skb = alloc_skb(size, gfp_any()); |
1848 | if (!skb) { | 1852 | if (!skb) { |
1849 | netlink_set_err(rtnl, 0, RTMGRP_IPV6_ROUTE, ENOBUFS); | 1853 | netlink_set_err(rtnl, 0, RTMGRP_IPV6_ROUTE, ENOBUFS); |
1850 | return; | 1854 | return; |
1851 | } | 1855 | } |
1852 | if (rt6_fill_node(skb, rt, NULL, NULL, 0, event, 0, 0, nlh, 0, 0) < 0) { | 1856 | if (rt6_fill_node(skb, rt, NULL, NULL, 0, event, pid, seq, 0, 0) < 0) { |
1853 | kfree_skb(skb); | 1857 | kfree_skb(skb); |
1854 | netlink_set_err(rtnl, 0, RTMGRP_IPV6_ROUTE, EINVAL); | 1858 | netlink_set_err(rtnl, 0, RTMGRP_IPV6_ROUTE, EINVAL); |
1855 | return; | 1859 | return; |
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c index ffcadd68b951..60c26c87277e 100644 --- a/net/ipv6/xfrm6_tunnel.c +++ b/net/ipv6/xfrm6_tunnel.c | |||
@@ -466,7 +466,7 @@ static void xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
466 | return; | 466 | return; |
467 | } | 467 | } |
468 | 468 | ||
469 | static int xfrm6_tunnel_init_state(struct xfrm_state *x, void *args) | 469 | static int xfrm6_tunnel_init_state(struct xfrm_state *x) |
470 | { | 470 | { |
471 | if (!x->props.mode) | 471 | if (!x->props.mode) |
472 | return -EINVAL; | 472 | return -EINVAL; |