X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=net%2Fdccp%2Fipv6.c;h=f7fe2a572d7bb6bafc27de0e16411eb6cc68b5fd;hb=a4056573873dc9fc506ce9293c4d01670101a637;hp=94d749e6d49439e77b4593a770abc9020699ef18;hpb=8eefca4888c986d993b2571eb31f0397a5d0a178;p=linux-2.6 diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index 94d749e6d4..f7fe2a572d 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c @@ -33,8 +33,7 @@ #include "ipv6.h" #include "feat.h" -/* Socket used for sending RSTs and ACKs */ -static struct sock *dccp_v6_ctl_sk; +/* The per-net dccp.v6_ctl_sk is used for sending RSTs and ACKs */ static struct inet_connection_sock_af_ops dccp_ipv6_mapped; static struct inet_connection_sock_af_ops dccp_ipv6_af_ops; @@ -95,7 +94,8 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, int err; __u64 seq; - sk = inet6_lookup(&init_net, &dccp_hashinfo, &hdr->daddr, dh->dccph_dport, + sk = inet6_lookup(dev_net(skb->dev), &dccp_hashinfo, + &hdr->daddr, dh->dccph_dport, &hdr->saddr, dh->dccph_sport, inet6_iif(skb)); if (sk == NULL) { @@ -296,6 +296,8 @@ static void dccp_v6_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb) struct ipv6hdr *rxip6h; struct sk_buff *skb; struct flowi fl; + struct net *net = dev_net(rxskb->dst->dev); + struct sock *ctl_sk = net->dccp.v6_ctl_sk; if (dccp_hdr(rxskb)->dccph_type == DCCP_PKT_RESET) return; @@ -303,7 +305,7 @@ static void dccp_v6_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb) if (!ipv6_unicast_destination(rxskb)) return; - skb = dccp_ctl_make_reset(dccp_v6_ctl_sk, rxskb); + skb = dccp_ctl_make_reset(ctl_sk, rxskb); if (skb == NULL) return; @@ -322,9 +324,9 @@ static void dccp_v6_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb) security_skb_classify_flow(rxskb, &fl); /* sk = NULL, but it is safe for now. RST socket required. */ - if (!ip6_dst_lookup(NULL, &skb->dst, &fl)) { + if (!ip6_dst_lookup(ctl_sk, &skb->dst, &fl)) { if (xfrm_lookup(&skb->dst, &fl, NULL, 0) >= 0) { - ip6_xmit(dccp_v6_ctl_sk, skb, &fl, NULL, 0); + ip6_xmit(ctl_sk, skb, &fl, NULL, 0); DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS); DCCP_INC_STATS_BH(DCCP_MIB_OUTRSTS); return; @@ -358,7 +360,7 @@ static struct sock *dccp_v6_hnd_req(struct sock *sk,struct sk_buff *skb) if (req != NULL) return dccp_check_req(sk, skb, req, prev); - nsk = __inet6_lookup_established(&init_net, &dccp_hashinfo, + nsk = __inet6_lookup_established(sock_net(sk), &dccp_hashinfo, &iph->saddr, dh->dccph_sport, &iph->daddr, ntohs(dh->dccph_dport), inet6_iif(skb)); @@ -419,7 +421,6 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb) ireq6 = inet6_rsk(req); ipv6_addr_copy(&ireq6->rmt_addr, &ipv6_hdr(skb)->saddr); ipv6_addr_copy(&ireq6->loc_addr, &ipv6_hdr(skb)->daddr); - ireq6->pktopts = NULL; if (ipv6_opt_accepted(sk, skb) || np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo || @@ -623,7 +624,7 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk, newinet->daddr = newinet->saddr = newinet->rcv_saddr = LOOPBACK4_IPV6; __inet6_hash(newsk); - inet_inherit_port(sk, newsk); + __inet_inherit_port(sk, newsk); return newsk; @@ -789,8 +790,8 @@ static int dccp_v6_rcv(struct sk_buff *skb) /* Step 2: * Look up flow ID in table and get corresponding socket */ - sk = __inet6_lookup(&init_net, &dccp_hashinfo, &ipv6_hdr(skb)->saddr, - dh->dccph_sport, + sk = __inet6_lookup(dev_net(skb->dst->dev), &dccp_hashinfo, + &ipv6_hdr(skb)->saddr, dh->dccph_sport, &ipv6_hdr(skb)->daddr, ntohs(dh->dccph_dport), inet6_iif(skb)); /* @@ -1171,6 +1172,25 @@ static struct inet_protosw dccp_v6_protosw = { .flags = INET_PROTOSW_ICSK, }; +static int dccp_v6_init_net(struct net *net) +{ + int err; + + err = inet_ctl_sock_create(&net->dccp.v6_ctl_sk, PF_INET6, + SOCK_DCCP, IPPROTO_DCCP, net); + return err; +} + +static void dccp_v6_exit_net(struct net *net) +{ + inet_ctl_sock_destroy(net->dccp.v6_ctl_sk); +} + +static struct pernet_operations dccp_v6_ops = { + .init = dccp_v6_init_net, + .exit = dccp_v6_exit_net, +}; + static int __init dccp_v6_init(void) { int err = proto_register(&dccp_v6_prot, 1); @@ -1184,13 +1204,13 @@ static int __init dccp_v6_init(void) inet6_register_protosw(&dccp_v6_protosw); - err = inet_ctl_sock_create(&dccp_v6_ctl_sk, PF_INET6, - SOCK_DCCP, IPPROTO_DCCP, &init_net); + err = register_pernet_subsys(&dccp_v6_ops); if (err != 0) - goto out_unregister_protosw; + goto out_destroy_ctl_sock; out: return err; -out_unregister_protosw: + +out_destroy_ctl_sock: inet6_del_protocol(&dccp_v6_protocol, IPPROTO_DCCP); inet6_unregister_protosw(&dccp_v6_protosw); out_unregister_proto: @@ -1200,7 +1220,7 @@ out_unregister_proto: static void __exit dccp_v6_exit(void) { - inet_ctl_sock_destroy(dccp_v6_ctl_sk); + unregister_pernet_subsys(&dccp_v6_ops); inet6_del_protocol(&dccp_v6_protocol, IPPROTO_DCCP); inet6_unregister_protosw(&dccp_v6_protosw); proto_unregister(&dccp_v6_prot);