ipv6.c (a432c771e2d9bc059ffe3028faf040c08b6a9f98) | ipv6.c (0c5dc070ff3d6246d22ddd931f23a6266249e3db) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* SCTP kernel implementation 3 * (C) Copyright IBM Corp. 2002, 2004 4 * Copyright (c) 2001 Nokia, Inc. 5 * Copyright (c) 2001 La Monte H.P. Yarroll 6 * Copyright (c) 2002-2003 Intel Corp. 7 * 8 * This file is part of the SCTP kernel implementation --- 108 unchanged lines hidden (view full) --- 117 118 return NOTIFY_DONE; 119} 120 121static struct notifier_block sctp_inet6addr_notifier = { 122 .notifier_call = sctp_inet6addr_event, 123}; 124 | 1// SPDX-License-Identifier: GPL-2.0-or-later 2/* SCTP kernel implementation 3 * (C) Copyright IBM Corp. 2002, 2004 4 * Copyright (c) 2001 Nokia, Inc. 5 * Copyright (c) 2001 La Monte H.P. Yarroll 6 * Copyright (c) 2002-2003 Intel Corp. 7 * 8 * This file is part of the SCTP kernel implementation --- 108 unchanged lines hidden (view full) --- 117 118 return NOTIFY_DONE; 119} 120 121static struct notifier_block sctp_inet6addr_notifier = { 122 .notifier_call = sctp_inet6addr_event, 123}; 124 |
125static void sctp_v6_err_handle(struct sctp_transport *t, struct sk_buff *skb, 126 __u8 type, __u8 code, __u32 info) | 125/* ICMP error handler. */ 126static int sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 127 u8 type, u8 code, int offset, __be32 info) |
127{ | 128{ |
128 struct sctp_association *asoc = t->asoc; 129 struct sock *sk = asoc->base.sk; | 129 struct inet6_dev *idev; 130 struct sock *sk; 131 struct sctp_association *asoc; 132 struct sctp_transport *transport; |
130 struct ipv6_pinfo *np; | 133 struct ipv6_pinfo *np; |
131 int err = 0; | 134 __u16 saveip, savesctp; 135 int err, ret = 0; 136 struct net *net = dev_net(skb->dev); |
132 | 137 |
138 idev = in6_dev_get(skb->dev); 139 140 /* Fix up skb to look at the embedded net header. */ 141 saveip = skb->network_header; 142 savesctp = skb->transport_header; 143 skb_reset_network_header(skb); 144 skb_set_transport_header(skb, offset); 145 sk = sctp_err_lookup(net, AF_INET6, skb, sctp_hdr(skb), &asoc, &transport); 146 /* Put back, the original pointers. */ 147 skb->network_header = saveip; 148 skb->transport_header = savesctp; 149 if (!sk) { 150 __ICMP6_INC_STATS(net, idev, ICMP6_MIB_INERRORS); 151 ret = -ENOENT; 152 goto out; 153 } 154 155 /* Warning: The sock lock is held. Remember to call 156 * sctp_err_finish! 157 */ 158 |
|
133 switch (type) { 134 case ICMPV6_PKT_TOOBIG: 135 if (ip6_sk_accept_pmtu(sk)) | 159 switch (type) { 160 case ICMPV6_PKT_TOOBIG: 161 if (ip6_sk_accept_pmtu(sk)) |
136 sctp_icmp_frag_needed(sk, asoc, t, info); 137 return; | 162 sctp_icmp_frag_needed(sk, asoc, transport, ntohl(info)); 163 goto out_unlock; |
138 case ICMPV6_PARAMPROB: 139 if (ICMPV6_UNK_NEXTHDR == code) { | 164 case ICMPV6_PARAMPROB: 165 if (ICMPV6_UNK_NEXTHDR == code) { |
140 sctp_icmp_proto_unreachable(sk, asoc, t); 141 return; | 166 sctp_icmp_proto_unreachable(sk, asoc, transport); 167 goto out_unlock; |
142 } 143 break; 144 case NDISC_REDIRECT: | 168 } 169 break; 170 case NDISC_REDIRECT: |
145 sctp_icmp_redirect(sk, t, skb); 146 return; | 171 sctp_icmp_redirect(sk, transport, skb); 172 goto out_unlock; |
147 default: 148 break; 149 } 150 151 np = inet6_sk(sk); 152 icmpv6_err_convert(type, code, &err); 153 if (!sock_owned_by_user(sk) && np->recverr) { 154 sk->sk_err = err; 155 sk->sk_error_report(sk); | 173 default: 174 break; 175 } 176 177 np = inet6_sk(sk); 178 icmpv6_err_convert(type, code, &err); 179 if (!sock_owned_by_user(sk) && np->recverr) { 180 sk->sk_err = err; 181 sk->sk_error_report(sk); |
156 } else { | 182 } else { /* Only an error on timeout */ |
157 sk->sk_err_soft = err; 158 } | 183 sk->sk_err_soft = err; 184 } |
159} | |
160 | 185 |
161/* ICMP error handler. */ 162static int sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 163 u8 type, u8 code, int offset, __be32 info) 164{ 165 struct net *net = dev_net(skb->dev); 166 struct sctp_transport *transport; 167 struct sctp_association *asoc; 168 __u16 saveip, savesctp; 169 struct sock *sk; 170 171 /* Fix up skb to look at the embedded net header. */ 172 saveip = skb->network_header; 173 savesctp = skb->transport_header; 174 skb_reset_network_header(skb); 175 skb_set_transport_header(skb, offset); 176 sk = sctp_err_lookup(net, AF_INET6, skb, sctp_hdr(skb), &asoc, &transport); 177 /* Put back, the original pointers. */ 178 skb->network_header = saveip; 179 skb->transport_header = savesctp; 180 if (!sk) { 181 __ICMP6_INC_STATS(net, __in6_dev_get(skb->dev), ICMP6_MIB_INERRORS); 182 return -ENOENT; 183 } 184 185 sctp_v6_err_handle(transport, skb, type, code, ntohl(info)); | 186out_unlock: |
186 sctp_err_finish(sk, transport); | 187 sctp_err_finish(sk, transport); |
188out: 189 if (likely(idev != NULL)) 190 in6_dev_put(idev); |
|
187 | 191 |
188 return 0; | 192 return ret; |
189} 190 | 193} 194 |
191int sctp_udp_v6_err(struct sock *sk, struct sk_buff *skb) 192{ 193 struct net *net = dev_net(skb->dev); 194 struct sctp_association *asoc; 195 struct sctp_transport *t; 196 struct icmp6hdr *hdr; 197 __u32 info = 0; 198 199 skb->transport_header += sizeof(struct udphdr); 200 sk = sctp_err_lookup(net, AF_INET6, skb, sctp_hdr(skb), &asoc, &t); 201 if (!sk) { 202 __ICMP6_INC_STATS(net, __in6_dev_get(skb->dev), ICMP6_MIB_INERRORS); 203 return -ENOENT; 204 } 205 206 skb->transport_header -= sizeof(struct udphdr); 207 hdr = (struct icmp6hdr *)(skb_network_header(skb) - sizeof(struct icmp6hdr)); 208 if (hdr->icmp6_type == NDISC_REDIRECT) { 209 /* can't be handled without outer ip6hdr known, leave it to udpv6_err */ 210 sctp_err_finish(sk, t); 211 return 0; 212 } 213 if (hdr->icmp6_type == ICMPV6_PKT_TOOBIG) 214 info = ntohl(hdr->icmp6_mtu); 215 sctp_v6_err_handle(t, skb, hdr->icmp6_type, hdr->icmp6_code, info); 216 217 sctp_err_finish(sk, t); 218 return 1; 219} 220 | |
221static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *t) 222{ 223 struct dst_entry *dst = dst_clone(t->dst); 224 struct flowi6 *fl6 = &t->fl.u.ip6; 225 struct sock *sk = skb->sk; 226 struct ipv6_pinfo *np = inet6_sk(sk); 227 __u8 tclass = np->tclass; 228 __be32 label; --- 343 unchanged lines hidden (view full) --- 572 sk->sk_v6_daddr.s6_addr32[2] = htonl(0x0000ffff); 573 sk->sk_v6_daddr.s6_addr32[3] = addr->v4.sin_addr.s_addr; 574 } else { 575 sk->sk_v6_daddr = addr->v6.sin6_addr; 576 } 577} 578 579/* Initialize a sctp_addr from an address parameter. */ | 195static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *t) 196{ 197 struct dst_entry *dst = dst_clone(t->dst); 198 struct flowi6 *fl6 = &t->fl.u.ip6; 199 struct sock *sk = skb->sk; 200 struct ipv6_pinfo *np = inet6_sk(sk); 201 __u8 tclass = np->tclass; 202 __be32 label; --- 343 unchanged lines hidden (view full) --- 546 sk->sk_v6_daddr.s6_addr32[2] = htonl(0x0000ffff); 547 sk->sk_v6_daddr.s6_addr32[3] = addr->v4.sin_addr.s_addr; 548 } else { 549 sk->sk_v6_daddr = addr->v6.sin6_addr; 550 } 551} 552 553/* Initialize a sctp_addr from an address parameter. */ |
580static void sctp_v6_from_addr_param(union sctp_addr *addr, | 554static bool sctp_v6_from_addr_param(union sctp_addr *addr, |
581 union sctp_addr_param *param, 582 __be16 port, int iif) 583{ | 555 union sctp_addr_param *param, 556 __be16 port, int iif) 557{ |
558 if (ntohs(param->v6.param_hdr.length) < sizeof(struct sctp_ipv6addr_param)) 559 return false; 560 |
|
584 addr->v6.sin6_family = AF_INET6; 585 addr->v6.sin6_port = port; 586 addr->v6.sin6_flowinfo = 0; /* BUG */ 587 addr->v6.sin6_addr = param->v6.addr; 588 addr->v6.sin6_scope_id = iif; | 561 addr->v6.sin6_family = AF_INET6; 562 addr->v6.sin6_port = port; 563 addr->v6.sin6_flowinfo = 0; /* BUG */ 564 addr->v6.sin6_addr = param->v6.addr; 565 addr->v6.sin6_scope_id = iif; |
566 567 return true; |
|
589} 590 591/* Initialize an address parameter from a sctp_addr and return the length 592 * of the address parameter. 593 */ 594static int sctp_v6_to_addr_param(const union sctp_addr *addr, 595 union sctp_addr_param *param) 596{ --- 615 unchanged lines hidden --- | 568} 569 570/* Initialize an address parameter from a sctp_addr and return the length 571 * of the address parameter. 572 */ 573static int sctp_v6_to_addr_param(const union sctp_addr *addr, 574 union sctp_addr_param *param) 575{ --- 615 unchanged lines hidden --- |