icmp.c (188933ac139a6f8ab06cad369bd0200af947b00d) icmp.c (63159f29be1df7f93563a8a0f78c5e65fc844ed6)
1/*
2 * Internet Control Message Protocol (ICMPv6)
3 * Linux INET6 implementation
4 *
5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt>
7 *
8 * Based on net/ipv4/icmp.c

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

155 ptr = ipv6_skip_exthdr(skb, ptr, &nexthdr, &frag_off);
156 if (ptr < 0)
157 return false;
158 if (nexthdr == IPPROTO_ICMPV6) {
159 u8 _type, *tp;
160 tp = skb_header_pointer(skb,
161 ptr+offsetof(struct icmp6hdr, icmp6_type),
162 sizeof(_type), &_type);
1/*
2 * Internet Control Message Protocol (ICMPv6)
3 * Linux INET6 implementation
4 *
5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt>
7 *
8 * Based on net/ipv4/icmp.c

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

155 ptr = ipv6_skip_exthdr(skb, ptr, &nexthdr, &frag_off);
156 if (ptr < 0)
157 return false;
158 if (nexthdr == IPPROTO_ICMPV6) {
159 u8 _type, *tp;
160 tp = skb_header_pointer(skb,
161 ptr+offsetof(struct icmp6hdr, icmp6_type),
162 sizeof(_type), &_type);
163 if (tp == NULL ||
164 !(*tp & ICMPV6_INFOMSG_MASK))
163 if (!tp || !(*tp & ICMPV6_INFOMSG_MASK))
165 return true;
166 }
167 return false;
168}
169
170/*
171 * Check the ICMP output rate limit
172 */

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

226 */
227
228static bool opt_unrec(struct sk_buff *skb, __u32 offset)
229{
230 u8 _optval, *op;
231
232 offset += skb_network_offset(skb);
233 op = skb_header_pointer(skb, offset, sizeof(_optval), &_optval);
164 return true;
165 }
166 return false;
167}
168
169/*
170 * Check the ICMP output rate limit
171 */

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

225 */
226
227static bool opt_unrec(struct sk_buff *skb, __u32 offset)
228{
229 u8 _optval, *op;
230
231 offset += skb_network_offset(skb);
232 op = skb_header_pointer(skb, offset, sizeof(_optval), &_optval);
234 if (op == NULL)
233 if (!op)
235 return true;
236 return (*op & 0xC0) == 0x80;
237}
238
239int icmpv6_push_pending_frames(struct sock *sk, struct flowi6 *fl6,
240 struct icmp6hdr *thdr, int len)
241{
242 struct sk_buff *skb;
243 struct icmp6hdr *icmp6h;
244 int err = 0;
245
246 skb = skb_peek(&sk->sk_write_queue);
234 return true;
235 return (*op & 0xC0) == 0x80;
236}
237
238int icmpv6_push_pending_frames(struct sock *sk, struct flowi6 *fl6,
239 struct icmp6hdr *thdr, int len)
240{
241 struct sk_buff *skb;
242 struct icmp6hdr *icmp6h;
243 int err = 0;
244
245 skb = skb_peek(&sk->sk_write_queue);
247 if (skb == NULL)
246 if (!skb)
248 goto out;
249
250 icmp6h = icmp6_hdr(skb);
251 memcpy(icmp6h, thdr, sizeof(struct icmp6hdr));
252 icmp6h->icmp6_cksum = 0;
253
254 if (skb_queue_len(&sk->sk_write_queue) == 1) {
255 skb->csum = csum_partial(icmp6h,

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

474 fl6.saddr = *saddr;
475 fl6.flowi6_mark = mark;
476 fl6.flowi6_oif = iif;
477 fl6.fl6_icmp_type = type;
478 fl6.fl6_icmp_code = code;
479 security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
480
481 sk = icmpv6_xmit_lock(net);
247 goto out;
248
249 icmp6h = icmp6_hdr(skb);
250 memcpy(icmp6h, thdr, sizeof(struct icmp6hdr));
251 icmp6h->icmp6_cksum = 0;
252
253 if (skb_queue_len(&sk->sk_write_queue) == 1) {
254 skb->csum = csum_partial(icmp6h,

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

473 fl6.saddr = *saddr;
474 fl6.flowi6_mark = mark;
475 fl6.flowi6_oif = iif;
476 fl6.fl6_icmp_type = type;
477 fl6.fl6_icmp_code = code;
478 security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
479
480 sk = icmpv6_xmit_lock(net);
482 if (sk == NULL)
481 if (!sk)
483 return;
484 sk->sk_mark = mark;
485 np = inet6_sk(sk);
486
487 if (!icmpv6_xrlim_allow(sk, type, &fl6))
488 goto out;
489
490 tmp_hdr.icmp6_type = type;

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

577 if (saddr)
578 fl6.saddr = *saddr;
579 fl6.flowi6_oif = skb->dev->ifindex;
580 fl6.fl6_icmp_type = ICMPV6_ECHO_REPLY;
581 fl6.flowi6_mark = mark;
582 security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
583
584 sk = icmpv6_xmit_lock(net);
482 return;
483 sk->sk_mark = mark;
484 np = inet6_sk(sk);
485
486 if (!icmpv6_xrlim_allow(sk, type, &fl6))
487 goto out;
488
489 tmp_hdr.icmp6_type = type;

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

576 if (saddr)
577 fl6.saddr = *saddr;
578 fl6.flowi6_oif = skb->dev->ifindex;
579 fl6.fl6_icmp_type = ICMPV6_ECHO_REPLY;
580 fl6.flowi6_mark = mark;
581 security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
582
583 sk = icmpv6_xmit_lock(net);
585 if (sk == NULL)
584 if (!sk)
586 return;
587 sk->sk_mark = mark;
588 np = inet6_sk(sk);
589
590 if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr))
591 fl6.flowi6_oif = np->mcast_oif;
592 else if (!fl6.flowi6_oif)
593 fl6.flowi6_oif = np->ucast_oif;

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

834
835static int __net_init icmpv6_sk_init(struct net *net)
836{
837 struct sock *sk;
838 int err, i, j;
839
840 net->ipv6.icmp_sk =
841 kzalloc(nr_cpu_ids * sizeof(struct sock *), GFP_KERNEL);
585 return;
586 sk->sk_mark = mark;
587 np = inet6_sk(sk);
588
589 if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr))
590 fl6.flowi6_oif = np->mcast_oif;
591 else if (!fl6.flowi6_oif)
592 fl6.flowi6_oif = np->ucast_oif;

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

833
834static int __net_init icmpv6_sk_init(struct net *net)
835{
836 struct sock *sk;
837 int err, i, j;
838
839 net->ipv6.icmp_sk =
840 kzalloc(nr_cpu_ids * sizeof(struct sock *), GFP_KERNEL);
842 if (net->ipv6.icmp_sk == NULL)
841 if (!net->ipv6.icmp_sk)
843 return -ENOMEM;
844
845 for_each_possible_cpu(i) {
846 err = inet_ctl_sock_create(&sk, PF_INET6,
847 SOCK_RAW, IPPROTO_ICMPV6, net);
848 if (err < 0) {
849 pr_err("Failed to initialize the ICMP6 control socket (err %d)\n",
850 err);

--- 169 unchanged lines hidden ---
842 return -ENOMEM;
843
844 for_each_possible_cpu(i) {
845 err = inet_ctl_sock_create(&sk, PF_INET6,
846 SOCK_RAW, IPPROTO_ICMPV6, net);
847 if (err < 0) {
848 pr_err("Failed to initialize the ICMP6 control socket (err %d)\n",
849 err);

--- 169 unchanged lines hidden ---